Loading drivers/platform/msm/sps/sps.c +35 −0 Original line number Original line Diff line number Diff line Loading @@ -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 * * Loading drivers/platform/msm/sps/sps_bam.c +58 −0 Original line number Original line Diff line number Diff line Loading @@ -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 * * Loading drivers/platform/msm/sps/sps_bam.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -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_ */ include/linux/msm-sps.h +16 −0 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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_ */ Loading
drivers/platform/msm/sps/sps.c +35 −0 Original line number Original line Diff line number Diff line Loading @@ -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 * * Loading
drivers/platform/msm/sps/sps_bam.c +58 −0 Original line number Original line Diff line number Diff line Loading @@ -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 * * Loading
drivers/platform/msm/sps/sps_bam.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -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_ */
include/linux/msm-sps.h +16 −0 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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_ */