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

Commit edc6c8ae authored by Kyle Piefer's avatar Kyle Piefer
Browse files

msm: kgsl: Add a new marker for IFPC



The SET_MARKER packet is intended to be used for
preemption. Since we also need markers for IFPC,
add those as a separate marker. Also, make sure
the old way still works for firmware versions
that need it.

Change-Id: I35bf0b0745e1f9efff08f876d84e35521a68bd7a
Signed-off-by: default avatarKyle Piefer <kpiefer@codeaurora.org>
parent 76913944
Loading
Loading
Loading
Loading
+9 −1
Original line number Original line Diff line number Diff line
@@ -831,6 +831,13 @@ struct adreno_snapshot_data {
	struct adreno_snapshot_sizes *sect_sizes;
	struct adreno_snapshot_sizes *sect_sizes;
};
};


enum adreno_cp_marker_type {
	IFPC_DISABLE,
	IFPC_ENABLE,
	IB1LIST_START,
	IB1LIST_END,
};

struct adreno_gpudev {
struct adreno_gpudev {
	/*
	/*
	 * These registers are in a different location on different devices,
	 * These registers are in a different location on different devices,
@@ -878,7 +885,8 @@ struct adreno_gpudev {
				unsigned int *cmds,
				unsigned int *cmds,
				struct kgsl_context *context);
				struct kgsl_context *context);
	int (*preemption_yield_enable)(unsigned int *);
	int (*preemption_yield_enable)(unsigned int *);
	unsigned int (*set_marker)(unsigned int *cmds, int start);
	unsigned int (*set_marker)(unsigned int *cmds,
				enum adreno_cp_marker_type type);
	unsigned int (*preemption_post_ibsubmit)(
	unsigned int (*preemption_post_ibsubmit)(
				struct adreno_device *adreno_dev,
				struct adreno_device *adreno_dev,
				unsigned int *cmds);
				unsigned int *cmds);
+32 −0
Original line number Original line Diff line number Diff line
@@ -913,6 +913,38 @@ static int a6xx_rb_start(struct adreno_device *adreno_dev,
	return a6xx_post_start(adreno_dev);
	return a6xx_post_start(adreno_dev);
}
}


unsigned int a6xx_set_marker(
		unsigned int *cmds, enum adreno_cp_marker_type type)
{
	unsigned int cmd = 0;

	*cmds++ = cp_type7_packet(CP_SET_MARKER, 1);

	/*
	 * Indicate the beginning and end of the IB1 list with a SET_MARKER.
	 * Among other things, this will implicitly enable and disable
	 * preemption respectively. IFPC can also be disabled and enabled
	 * with a SET_MARKER. Bit 8 tells the CP the marker is for IFPC.
	 */
	switch (type) {
	case IFPC_DISABLE:
		cmd = 0x101;
		break;
	case IFPC_ENABLE:
		cmd = 0x100;
		break;
	case IB1LIST_START:
		cmd = 0xD;
		break;
	case IB1LIST_END:
		cmd = 0xE;
		break;
	}

	*cmds++ = cmd;
	return 2;
}

static int _load_firmware(struct kgsl_device *device, const char *fwfile,
static int _load_firmware(struct kgsl_device *device, const char *fwfile,
			  struct adreno_firmware *firmware)
			  struct adreno_firmware *firmware)
{
{
+2 −1
Original line number Original line Diff line number Diff line
@@ -100,7 +100,8 @@ unsigned int a6xx_preemption_pre_ibsubmit(struct adreno_device *adreno_dev,
		struct adreno_ringbuffer *rb,
		struct adreno_ringbuffer *rb,
		unsigned int *cmds, struct kgsl_context *context);
		unsigned int *cmds, struct kgsl_context *context);


unsigned int a6xx_set_marker(unsigned int *cmds, int start);
unsigned int a6xx_set_marker(unsigned int *cmds,
		enum adreno_cp_marker_type type);


void a6xx_preemption_callback(struct adreno_device *adreno_dev, int bit);
void a6xx_preemption_callback(struct adreno_device *adreno_dev, int bit);


+0 −17
Original line number Original line Diff line number Diff line
@@ -374,23 +374,6 @@ void a6xx_preemption_schedule(struct adreno_device *adreno_dev)
	mutex_unlock(&device->mutex);
	mutex_unlock(&device->mutex);
}
}


unsigned int a6xx_set_marker(unsigned int *cmds, int start)
{
	*cmds++ = cp_type7_packet(CP_SET_MARKER, 1);

	/*
	 * Indicate the beginning  and end of the IB1 list with a SET_MARKER.
	 * Among other things, this will implicitly enable and disable
	 * preemption respectively.
	 */
	if (start)
		*cmds++ = 0xD;
	else
		*cmds++ = 0xE;

	return 2;
}

unsigned int a6xx_preemption_pre_ibsubmit(
unsigned int a6xx_preemption_pre_ibsubmit(
		struct adreno_device *adreno_dev,
		struct adreno_device *adreno_dev,
		struct adreno_ringbuffer *rb,
		struct adreno_ringbuffer *rb,
+33 −5
Original line number Original line Diff line number Diff line
@@ -425,6 +425,7 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
	struct kgsl_context *context = NULL;
	struct kgsl_context *context = NULL;
	bool secured_ctxt = false;
	bool secured_ctxt = false;
	static unsigned int _seq_cnt;
	static unsigned int _seq_cnt;
	struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);


	if (drawctxt != NULL && kgsl_context_detached(&drawctxt->base) &&
	if (drawctxt != NULL && kgsl_context_detached(&drawctxt->base) &&
		!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))
		!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))
@@ -559,8 +560,13 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
		*ringcmds++ = KGSL_CMD_INTERNAL_IDENTIFIER;
		*ringcmds++ = KGSL_CMD_INTERNAL_IDENTIFIER;
	}
	}


	if (gpudev->set_marker)
	if (gpudev->set_marker) {
		ringcmds += gpudev->set_marker(ringcmds, 1);
		/* Firmware versions before 1.49 do not support IFPC markers */
		if (adreno_is_a6xx(adreno_dev) && (fw->version & 0xFFF) < 0x149)
			ringcmds += gpudev->set_marker(ringcmds, IB1LIST_START);
		else
			ringcmds += gpudev->set_marker(ringcmds, IFPC_DISABLE);
	}


	if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP) {
	if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP) {
		/* Disable protected mode for the fixup */
		/* Disable protected mode for the fixup */
@@ -680,8 +686,12 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
		*ringcmds++ = timestamp;
		*ringcmds++ = timestamp;
	}
	}


	if (gpudev->set_marker)
	if (gpudev->set_marker) {
		ringcmds += gpudev->set_marker(ringcmds, 0);
		if (adreno_is_a6xx(adreno_dev) && (fw->version & 0xFFF) < 0x149)
			ringcmds += gpudev->set_marker(ringcmds, IB1LIST_END);
		else
			ringcmds += gpudev->set_marker(ringcmds, IFPC_ENABLE);
	}


	if (adreno_is_a3xx(adreno_dev)) {
	if (adreno_is_a3xx(adreno_dev)) {
		/* Dummy set-constant to trigger context rollover */
		/* Dummy set-constant to trigger context rollover */
@@ -796,8 +806,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	struct kgsl_drawobj_profiling_buffer *profile_buffer = NULL;
	struct kgsl_drawobj_profiling_buffer *profile_buffer = NULL;
	unsigned int dwords = 0;
	unsigned int dwords = 0;
	struct adreno_submit_time local;
	struct adreno_submit_time local;

	struct kgsl_mem_entry *entry = cmdobj->profiling_buf_entry;
	struct kgsl_mem_entry *entry = cmdobj->profiling_buf_entry;
	struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);
	bool set_ib1list_marker = false;


	if (entry)
	if (entry)
		profile_buffer = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
		profile_buffer = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
@@ -907,6 +918,17 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
			dwords += 8;
			dwords += 8;
	}
	}


	/*
	 * Prior to SQE FW version 1.49, there was only one marker for
	 * both preemption and IFPC. Only include the IB1LIST markers if
	 * we are using a firmware that supports them.
	 */
	if (gpudev->set_marker && numibs && adreno_is_a6xx(adreno_dev) &&
			((fw->version & 0xFFF) >= 0x149)) {
		set_ib1list_marker = true;
		dwords += 4;
	}

	if (gpudev->ccu_invalidate)
	if (gpudev->ccu_invalidate)
		dwords += 4;
		dwords += 4;


@@ -940,6 +962,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	}
	}


	if (numibs) {
	if (numibs) {
		if (set_ib1list_marker)
			cmds += gpudev->set_marker(cmds, IB1LIST_START);

		list_for_each_entry(ib, &cmdobj->cmdlist, node) {
		list_for_each_entry(ib, &cmdobj->cmdlist, node) {
			/*
			/*
			 * Skip 0 sized IBs - these are presumed to have been
			 * Skip 0 sized IBs - these are presumed to have been
@@ -958,6 +983,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
			/* preamble is required on only for first command */
			/* preamble is required on only for first command */
			use_preamble = false;
			use_preamble = false;
		}
		}

		if (set_ib1list_marker)
			cmds += gpudev->set_marker(cmds, IB1LIST_END);
	}
	}


	if (gpudev->ccu_invalidate)
	if (gpudev->ccu_invalidate)