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

Commit cdcc02a6 authored by Tarun Karra's avatar Tarun Karra Committed by Jordan Crouse
Browse files

msm: kgsl: Get CP_RPTR from register instead of shadow memory



Sometimes the RPTR shadow memory is unreliable causing timeouts
in adreno_idle().  Read it directly from the register instead.

Change-Id: Icae7521edd9723610c41f320c6a5c99f57bec7f5
Signed-off-by: default avatarTarun Karra <tkarra@codeaurora.org>
parent 2be44f7c
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -646,8 +646,6 @@ static void adreno_cleanup_pt(struct kgsl_device *device,

	kgsl_mmu_unmap(pagetable, &rb->buffer_desc);

	kgsl_mmu_unmap(pagetable, &rb->memptrs_desc);

	kgsl_mmu_unmap(pagetable, &device->memstore);

	kgsl_mmu_unmap(pagetable, &adreno_dev->pwron_fixup);
@@ -668,13 +666,10 @@ static int adreno_setup_pt(struct kgsl_device *device,

	/*
	 * ALERT: Order of these mapping is important to
	 * Keep the most used entries like memptrs, memstore
	 * Keep the most used entries like memstore
	 * and mmu setstate memory by TLB prefetcher.
	 */

	if (!result)
		result = kgsl_mmu_map_global(pagetable, &rb->memptrs_desc);

	if (!result)
		result = kgsl_mmu_map_global(pagetable, &device->memstore);

@@ -2523,9 +2518,6 @@ struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
	if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr, size))
		return &ringbuffer->buffer_desc;

	if (kgsl_gpuaddr_in_memdesc(&ringbuffer->memptrs_desc, gpuaddr, size))
		return &ringbuffer->memptrs_desc;

	if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr, size))
		return &device->memstore;

+15 −0
Original line number Diff line number Diff line
@@ -986,4 +986,19 @@ static inline int adreno_bootstrap_ucode(struct adreno_device *adreno_dev)
		return 0;
}

/**
 * adreno_get_rptr() - Get the current ringbuffer read pointer
 * @rb: Pointer the ringbuffer to query
 *
 * Get the current read pointer from the GPU register.
 */
static inline unsigned int
adreno_get_rptr(struct adreno_ringbuffer *rb)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device);
	unsigned int result;
	adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &result);
	return result;
}

#endif /*__ADRENO_H */
+4 −26
Original line number Diff line number Diff line
@@ -369,30 +369,23 @@ void _ringbuffer_setup_common(struct adreno_ringbuffer *rb)
	struct kgsl_device *device = rb->device;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	kgsl_sharedmem_set(rb->device, &rb->memptrs_desc, 0, 0,
			   sizeof(struct kgsl_rbmemptrs));

	kgsl_sharedmem_set(rb->device, &rb->buffer_desc, 0, 0xAA,
			   (rb->sizedwords << 2));

	/*
	 * The size of the ringbuffer in the hardware is the log2
	 * representation of the size in quadwords (sizedwords / 2)
	 * blksize is the log2 of the number of quadwords to read before
	 * updating the memory RPTR
	 * representation of the size in quadwords (sizedwords / 2).
	 * Also disable the host RPTR shadow register as it might be unreliable
	 * in certain circumstances.
	 */

	adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_CNTL,
		(ilog2(rb->sizedwords >> 1) & 0x3F) |
		((ilog2(KGSL_RB_BLKSIZE >> 3) & 0x3F) << 8));
		(1 << 27));

	adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE,
					rb->buffer_desc.gpuaddr);

	adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_RPTR_ADDR,
				rb->memptrs_desc.gpuaddr +
				GSL_RB_MEMPTRS_RPTR_OFFSET);

	/* setup scratch/timestamp */
	adreno_writereg(adreno_dev, ADRENO_REG_SCRATCH_ADDR,
				device->memstore.gpuaddr +
@@ -579,20 +572,6 @@ int adreno_ringbuffer_init(struct kgsl_device *device)
		return status;
	}

	/* allocate memory for polling and timestamps */
	/* This really can be at 4 byte alignment boundry but for using MMU
	 * we need to make it at page boundary */
	status = kgsl_allocate_contiguous(&rb->memptrs_desc,
		sizeof(struct kgsl_rbmemptrs));

	if (status != 0) {
		adreno_ringbuffer_close(rb);
		return status;
	}

	/* overlay structure on memptrs memory */
	rb->memptrs = (struct kgsl_rbmemptrs *) rb->memptrs_desc.hostptr;

	rb->global_ts = 0;

	return 0;
@@ -603,7 +582,6 @@ void adreno_ringbuffer_close(struct adreno_ringbuffer *rb)
	struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device);

	kgsl_sharedmem_free(&rb->buffer_desc);
	kgsl_sharedmem_free(&rb->memptrs_desc);

	kfree(adreno_dev->pfp_fw);
	kfree(adreno_dev->pm4_fw);
+0 −35
Original line number Diff line number Diff line
@@ -19,32 +19,16 @@
 */

#define KGSL_RB_SIZE (32 * 1024)
#define KGSL_RB_BLKSIZE 16

struct kgsl_device;
struct kgsl_device_private;

#define GSL_RB_MEMPTRS_SCRATCH_COUNT	 8
struct kgsl_rbmemptrs {
	int  rptr;
	int  wptr_poll;
};

#define GSL_RB_MEMPTRS_RPTR_OFFSET \
	(offsetof(struct kgsl_rbmemptrs, rptr))

#define GSL_RB_MEMPTRS_WPTRPOLL_OFFSET \
	(offsetof(struct kgsl_rbmemptrs, wptr_poll))

struct adreno_ringbuffer {
	struct kgsl_device *device;
	uint32_t flags;

	struct kgsl_memdesc buffer_desc;

	struct kgsl_memdesc memptrs_desc;
	struct kgsl_rbmemptrs *memptrs;

	/*ringbuffer size */
	unsigned int sizedwords;

@@ -66,25 +50,6 @@ struct adreno_ringbuffer {
/* enable timestamp (...scratch0) memory shadowing */
#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x1

/* mem rptr */
#define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */

/**
 * adreno_get_rptr - Get the current ringbuffer read pointer
 * @rb -  the ringbuffer
 *
 * Get the current read pointer, which is written by the GPU.
 */
static inline unsigned int
adreno_get_rptr(struct adreno_ringbuffer *rb)
{
	unsigned int result = rb->memptrs->rptr;
	rmb();
	return result;
}

#define GSL_RB_CNTL_POLL_EN 0x0 /* disable */

/*
 * protected mode error checking below register address 0x800
 * note: if CP_INTERRUPT packet is used then checking needs