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

Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next



- fix for potential out-of-bounds reads in the perfmon ioctl
  implementation from Christian
- override to expose proper feature flags for the GC400 found on the
  STM32MP1 SoC, also from Christian
- Guido fixed an issue where we would spuriously fail to enter
  runtime suspend due to a new GPU engine status bit on GC7000
- tree-wide change from Gustavo to get rid of zero-length arrays
- fix for missed TS cache flush on GC7000, leading to spurious
  MMU faults from me
- request pages from DMA32 zone on systems where we can't address
  all present memory from me

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Lucas Stach <l.stach@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/74d9c6d19099fdba6c6795204a6aa445b7930c79.camel@pengutronix.de
parents cb7adfd6 f232d9ec
Loading
Loading
Loading
Loading
+55 −5
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@


#include "common.xml.h"
#include "common.xml.h"
#include "state.xml.h"
#include "state.xml.h"
#include "state_blt.xml.h"
#include "state_hi.xml.h"
#include "state_hi.xml.h"
#include "state_3d.xml.h"
#include "state_3d.xml.h"
#include "cmdstream.xml.h"
#include "cmdstream.xml.h"
@@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;
	unsigned int waitlink_offset = buffer->user_size - 16;
	unsigned int waitlink_offset = buffer->user_size - 16;
	u32 link_target, flush = 0;
	u32 link_target, flush = 0;
	bool has_blt = !!(gpu->identity.minor_features5 &
			  chipMinorFeatures5_BLT_ENGINE);


	lockdep_assert_held(&gpu->lock);
	lockdep_assert_held(&gpu->lock);


@@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
	if (flush) {
	if (flush) {
		unsigned int dwords = 7;
		unsigned int dwords = 7;


		if (has_blt)
			dwords += 10;

		link_target = etnaviv_buffer_reserve(gpu, buffer, dwords);
		link_target = etnaviv_buffer_reserve(gpu, buffer, dwords);


		CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		if (has_blt) {
			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
			CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
			CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
		}
		CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush);
		CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush);
		if (gpu->exec_state == ETNA_PIPE_3D)
		if (gpu->exec_state == ETNA_PIPE_3D) {
			if (has_blt) {
				CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
				CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
				CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
			} else {
				CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
				CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
					       VIVS_TS_FLUSH_CACHE_FLUSH);
					       VIVS_TS_FLUSH_CACHE_FLUSH);
			}
		}
		CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
		if (has_blt) {
			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
			CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
			CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
		}
		CMD_END(buffer);
		CMD_END(buffer);


		etnaviv_buffer_replace_wait(buffer, waitlink_offset,
		etnaviv_buffer_replace_wait(buffer, waitlink_offset,
@@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
	bool switch_mmu_context = gpu->mmu_context != mmu_context;
	bool switch_mmu_context = gpu->mmu_context != mmu_context;
	unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq);
	unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq);
	bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;
	bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;
	bool has_blt = !!(gpu->identity.minor_features5 &
			  chipMinorFeatures5_BLT_ENGINE);


	lockdep_assert_held(&gpu->lock);
	lockdep_assert_held(&gpu->lock);


@@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
	 * 2 semaphore stall + 1 event + 1 wait + 1 link.
	 * 2 semaphore stall + 1 event + 1 wait + 1 link.
	 */
	 */
	return_dwords = 7;
	return_dwords = 7;

	/*
	 * When the BLT engine is present we need 6 more dwords in the return
	 * target: 3 enable/flush/disable + 4 enable/semaphore stall/disable,
	 * but we don't need the normal TS flush state.
	 */
	if (has_blt)
		return_dwords += 6;

	return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
	return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
	CMD_LINK(cmdbuf, return_dwords, return_target);
	CMD_LINK(cmdbuf, return_dwords, return_target);


@@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
		CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
		CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
				       VIVS_GL_FLUSH_CACHE_DEPTH |
				       VIVS_GL_FLUSH_CACHE_DEPTH |
				       VIVS_GL_FLUSH_CACHE_COLOR);
				       VIVS_GL_FLUSH_CACHE_COLOR);
		if (has_blt) {
			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
			CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
		} else {
			CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
			CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
					       VIVS_TS_FLUSH_CACHE_FLUSH);
					       VIVS_TS_FLUSH_CACHE_FLUSH);
		}
		}
	}
	CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
	CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
	CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
	CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);

	if (has_blt) {
		CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
		CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
		CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
		CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
	}

	CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
	CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
		       VIVS_GL_EVENT_FROM_PE);
		       VIVS_GL_EVENT_FROM_PE);
	CMD_WAIT(buffer);
	CMD_WAIT(buffer);
+1 −0
Original line number Original line Diff line number Diff line
@@ -551,6 +551,7 @@ static int etnaviv_bind(struct device *dev)
	mutex_init(&priv->gem_lock);
	mutex_init(&priv->gem_lock);
	INIT_LIST_HEAD(&priv->gem_list);
	INIT_LIST_HEAD(&priv->gem_list);
	priv->num_gpus = 0;
	priv->num_gpus = 0;
	priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;


	priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
	priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
	if (IS_ERR(priv->cmdbuf_suballoc)) {
	if (IS_ERR(priv->cmdbuf_suballoc)) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ struct etnaviv_drm_private {
	int num_gpus;
	int num_gpus;
	struct device_dma_parameters dma_parms;
	struct device_dma_parameters dma_parms;
	struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
	struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
	gfp_t shm_gfp_mask;


	struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
	struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
	struct etnaviv_iommu_global *mmu_global;
	struct etnaviv_iommu_global *mmu_global;
+2 −2
Original line number Original line Diff line number Diff line
@@ -602,6 +602,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
	u32 size, u32 flags, u32 *handle)
	u32 size, u32 flags, u32 *handle)
{
{
	struct etnaviv_drm_private *priv = dev->dev_private;
	struct drm_gem_object *obj = NULL;
	struct drm_gem_object *obj = NULL;
	int ret;
	int ret;


@@ -624,8 +625,7 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
	 * above new_inode() why this is required _and_ expected if you're
	 * above new_inode() why this is required _and_ expected if you're
	 * going to pin these pages.
	 * going to pin these pages.
	 */
	 */
	mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER |
	mapping_set_gfp_mask(obj->filp->f_mapping, priv->shm_gfp_mask);
			     __GFP_RETRY_MAYFAIL | __GFP_NOWARN);


	etnaviv_gem_obj_add(dev, obj);
	etnaviv_gem_obj_add(dev, obj);


+1 −1
Original line number Original line Diff line number Diff line
@@ -105,7 +105,7 @@ struct etnaviv_gem_submit {
	unsigned int nr_pmrs;
	unsigned int nr_pmrs;
	struct etnaviv_perfmon_request *pmrs;
	struct etnaviv_perfmon_request *pmrs;
	unsigned int nr_bos;
	unsigned int nr_bos;
	struct etnaviv_gem_submit_bo bos[0];
	struct etnaviv_gem_submit_bo bos[];
	/* No new members here, the previous one is variable-length! */
	/* No new members here, the previous one is variable-length! */
};
};


Loading