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

Commit 43f22f77 authored by Yan He's avatar Yan He Committed by Gerrit - the friendly Code Review server
Browse files

msm: sps: support ZLT injection



Add the support to inject a ZLT descriptor with EOT, so that a peripheral
of BAM can respond to BAM to close pending descriptors.

Change-Id: I0db774de8f00cca02e895f45530a84f47c9dfe00
Signed-off-by: default avatarYan He <yanhe@codeaurora.org>
parent 9f5234bb
Loading
Loading
Loading
Loading
+35 −0
Original line number Original line Diff line number Diff line
@@ -2528,6 +2528,41 @@ int sps_get_bam_addr(unsigned long dev, phys_addr_t *base,
}
}
EXPORT_SYMBOL(sps_get_bam_addr);
EXPORT_SYMBOL(sps_get_bam_addr);


/*
 * Inject a ZLT with EOT for a BAM pipe
 */
int sps_pipe_inject_zlt(unsigned long dev, u32 pipe_index)
{
	struct sps_bam *bam;
	int rc;

	if (!dev) {
		SPS_ERR(sps, "sps:%s:BAM handle is NULL.\n", __func__);
		return SPS_ERROR;
	}

	if (pipe_index >= BAM_MAX_PIPES) {
		SPS_ERR(sps, "sps:%s:pipe index is invalid.\n", __func__);
		return SPS_ERROR;
	}

	bam = sps_h2bam(dev);
	if (bam == NULL) {
		SPS_ERR(sps, "sps:%s:BAM is not found by handle.\n", __func__);
		return SPS_ERROR;
	}

	SPS_DBG(bam, "sps:%s; BAM: %pa; pipe index:%d.\n",
		__func__, BAM_ID(bam), pipe_index);

	rc = sps_bam_pipe_inject_zlt(bam, pipe_index);
	if (rc)
		SPS_ERR(bam, "sps:%s:failed to inject a ZLT.\n", __func__);

	return rc;
}
EXPORT_SYMBOL(sps_pipe_inject_zlt);

/**
/**
 * Allocate client state context
 * Allocate client state context
 *
 *
+58 −0
Original line number Original line Diff line number Diff line
@@ -1562,6 +1562,64 @@ int sps_bam_pipe_transfer(struct sps_bam *dev,
	return 0;
	return 0;
}
}


int sps_bam_pipe_inject_zlt(struct sps_bam *dev, u32 pipe_index)
{
	struct sps_pipe *pipe = dev->pipes[pipe_index];
	struct sps_iovec *desc;
	u32 read_p, write_p, next_write;

	if (pipe->state & BAM_STATE_BAM2BAM)
		SPS_DBG2(dev, "sps: BAM-to-BAM pipe: BAM %pa pipe %d\n",
			BAM_ID(dev), pipe_index);
	else
		SPS_DBG2(dev, "sps: BAM-to-System pipe: BAM %pa pipe %d\n",
			BAM_ID(dev), pipe_index);

	if (!(pipe->state & BAM_STATE_ENABLED)) {
		SPS_ERR(dev,
			"sps: BAM %pa pipe %d is not enabled.\n",
			BAM_ID(dev), pipe_index);
		return SPS_ERROR;
	}

	read_p = bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
	write_p = bam_pipe_get_desc_write_offset(&dev->base, pipe_index);

	SPS_DBG2(dev,
		"sps: BAM %pa pipe %d: read pointer:0x%x; write pointer:0x%x.\n",
		BAM_ID(dev), pipe_index, read_p, write_p);

	if (read_p == write_p) {
		SPS_ERR(dev,
			"sps: BAM %pa pipe %d: read pointer 0x%x is already equal to write pointer.\n",
			BAM_ID(dev), pipe_index, read_p);
		return SPS_ERROR;
	}

	next_write = write_p + sizeof(struct sps_iovec);
	if (next_write >= pipe->desc_size) {
		SPS_DBG2(dev,
			"sps: BAM %pa pipe %d: next write is 0x%x: wrap around.\n",
			BAM_ID(dev), pipe_index, next_write);
		next_write = 0;
	}

	desc = (struct sps_iovec *) (pipe->connect.desc.base + write_p);
	desc->addr = 0;
	desc->size = 0;
	desc->flags = SPS_IOVEC_FLAG_EOT;

	bam_pipe_set_desc_write_offset(&dev->base, pipe_index,
					       next_write);
	wmb(); /* update write pointer in HW */
	SPS_DBG2(dev,
		"sps: BAM %pa pipe %d: write pointer to tell HW: 0x%x; write pointer read from HW: 0x%x\n",
		BAM_ID(dev), pipe_index, next_write,
		bam_pipe_get_desc_write_offset(&dev->base, pipe_index));

	return 0;
}

/**
/**
 * Allocate an event tracking struct
 * Allocate an event tracking struct
 *
 *
+11 −0
Original line number Original line Diff line number Diff line
@@ -600,4 +600,15 @@ int sps_bam_check_irq(struct sps_bam *dev);
 * @return true if there is any desc pending
 * @return true if there is any desc pending
 */
 */
bool sps_bam_pipe_pending_desc(struct sps_bam *dev, u32 pipe_index);
bool sps_bam_pipe_pending_desc(struct sps_bam *dev, u32 pipe_index);

/*
 * sps_bam_pipe_inject_zlt - inject a ZLT with EOT.
 * @dev:	BAM device handle
 * @pipe_index:	pipe index
 *
 * This function injects a ZLT with EOT for a pipe of a BAM.
 *
 * Return: 0 on success, negative value on error
 */
int sps_bam_pipe_inject_zlt(struct sps_bam *dev, u32 pipe_index);
#endif	/* _SPSBAM_H_ */
#endif	/* _SPSBAM_H_ */
+16 −0
Original line number Original line Diff line number Diff line
@@ -1414,6 +1414,17 @@ int sps_bam_process_irq(unsigned long dev);
 */
 */
int sps_get_bam_addr(unsigned long dev, phys_addr_t *base,
int sps_get_bam_addr(unsigned long dev, phys_addr_t *base,
				u32 *size);
				u32 *size);

/*
 * sps_pipe_inject_zlt - inject a ZLT with EOT.
 * @dev:	BAM device handle
 * @pipe_index:	pipe index
 *
 * This function injects a ZLT with EOT for a pipe of a BAM.
 *
 * Return: 0 on success, negative value on error
 */
int sps_pipe_inject_zlt(unsigned long dev, u32 pipe_index);
#else
#else
static inline int sps_register_bam_device(const struct sps_bam_props
static inline int sps_register_bam_device(const struct sps_bam_props
			*bam_props, unsigned long *dev_handle)
			*bam_props, unsigned long *dev_handle)
@@ -1608,6 +1619,11 @@ static inline int sps_get_bam_addr(unsigned long dev, phys_addr_t *base,
{
{
	return -EPERM;
	return -EPERM;
}
}

static inline int sps_pipe_inject_zlt(unsigned long dev, u32 pipe_index)
{
	return -EPERM;
}
#endif
#endif


#endif /* _SPS_H_ */
#endif /* _SPS_H_ */