diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c index 841224d47fb1..3c37ffb421df 100644 --- a/drivers/platform/msm/sps/bam.c +++ b/drivers/platform/msm/sps/bam.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. */ /* Bus-Access-Manager (BAM) Hardware manager. */ @@ -1358,8 +1358,13 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param, bam_write_reg_field(base, P_FIFO_SIZES, pipe, P_DATA_FIFO_SIZE, param->data_size); - bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, peer_dest_addr); - + if (!(param->dummy_peer)) { + bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, + peer_dest_addr); + } else { + bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, + param->peer_phys_addr); + } SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d.peer_bam=0x%x.peer_pipe=%d\n", dev->base, pipe, diff --git a/drivers/platform/msm/sps/bam.h b/drivers/platform/msm/sps/bam.h index 8f4c39cab185..4ec9332aa0e8 100644 --- a/drivers/platform/msm/sps/bam.h +++ b/drivers/platform/msm/sps/bam.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. */ /* Bus-Access-Manager (BAM) Hardware manager functions API. */ @@ -75,6 +75,7 @@ struct bam_pipe_parameters { u32 peer_pipe; phys_addr_t data_base; /* Physical address of data FIFO */ u32 data_size; /* Size (bytes) of data FIFO */ + bool dummy_peer; }; /** diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c index 9b9059fc296f..7cccd0edd0fe 100644 --- a/drivers/platform/msm/sps/sps_bam.c +++ b/drivers/platform/msm/sps/sps_bam.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. */ #include /* u32 */ #include /* pr_info() */ @@ -865,13 +865,15 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, } /* Determine operational mode */ - if (other_pipe->bam != NULL) { + if ((bam_pipe->connect.options & SPS_O_DUMMY_PEER) || + other_pipe->bam != NULL) { unsigned long iova; - struct sps_bam *peer_bam = (struct sps_bam *)(other_pipe->bam); + struct sps_bam *peer_bam; /* BAM-to-BAM mode */ bam_pipe->state |= BAM_STATE_BAM2BAM; hw_params.mode = BAM_PIPE_MODE_BAM2BAM; - + if (!(bam_pipe->connect.options & SPS_O_DUMMY_PEER)) + peer_bam = (struct sps_bam *)(other_pipe->bam); if (dev->props.options & SPS_BAM_SMMU_EN) { if (bam_pipe->mode == SPS_MODE_SRC) iova = bam_pipe->connect.dest_iova; @@ -882,11 +884,21 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, BAM_ID(dev), pipe_index, (void *)iova); hw_params.peer_phys_addr = (u32)iova; } else { - hw_params.peer_phys_addr = peer_bam->props.phys_addr; + if (!(bam_pipe->connect.options & SPS_O_DUMMY_PEER)) + hw_params.peer_phys_addr = + peer_bam->props.phys_addr; + } + if (!(bam_pipe->connect.options & SPS_O_DUMMY_PEER)) { + hw_params.peer_phys_addr = + bam_pipe->connect.destination; + hw_params.peer_pipe = + bam_pipe->connect.dest_pipe_index; + } else { + hw_params.peer_phys_addr = + bam_pipe->connect.destination; + hw_params.peer_pipe = other_pipe->pipe_index; + hw_params.dummy_peer = true; } - - hw_params.peer_pipe = other_pipe->pipe_index; - /* Verify FIFO buffers are allocated for BAM-to-BAM pipes */ if (map->desc.phys_base == SPS_ADDR_INVALID || map->data.phys_base == SPS_ADDR_INVALID || diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c index 81f81b8329ce..b8864e224e3b 100644 --- a/drivers/platform/msm/sps/sps_rm.c +++ b/drivers/platform/msm/sps/sps_rm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2011-2015, 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015, 2017-2020, The Linux Foundation. All rights reserved. */ /* Resource management for the SPS device driver. */ @@ -396,14 +396,18 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) } map->src.pipe_index = SPS_BAM_PIPE_INVALID; } - map->dest.bam = sps_h2bam(map->dest.dev); - if (map->dest.bam == NULL) { - if (map->dest.dev != SPS_DEV_HANDLE_MEM) { - SPS_ERR(sps, "sps:Invalid BAM handle: %pK\n", - (void *)(&map->dest.dev)); - goto exit_err; + + if (!(pipe->connect.options & SPS_O_DUMMY_PEER)) { + map->dest.bam = sps_h2bam(map->dest.dev); + if (map->dest.bam == NULL) { + if (map->dest.dev != SPS_DEV_HANDLE_MEM) { + SPS_ERR(sps, + "sps:Invalid BAM handle: %pK", + (void *)(&map->dest.dev)); + goto exit_err; + } + map->dest.pipe_index = SPS_BAM_PIPE_INVALID; } - map->dest.pipe_index = SPS_BAM_PIPE_INVALID; } /* Check the BAM device for the pipe */ @@ -496,7 +500,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) if (map->data.size == SPSRM_CLEAR) map->data.size = data_size; } else { - map->data.size = 0; + if (!(pipe->connect.options & SPS_O_DUMMY_PEER)) + map->data.size = 0; } if (map->desc.size > SPSRM_MAX_DESC_FIFO_SIZE) { SPS_ERR(sps, "sps:Invalid desc FIFO size: 0x%x\n", diff --git a/include/linux/msm-sps.h b/include/linux/msm-sps.h index b320730014f0..67247dcaa155 100644 --- a/include/linux/msm-sps.h +++ b/include/linux/msm-sps.h @@ -204,6 +204,8 @@ enum sps_option { SPS_O_NO_EP_SYNC = 0x40000000, /* Allow partial polling duing IRQ mode */ SPS_O_HYBRID = 0x80000000, + /* Allow dummy BAM connection */ + SPS_O_DUMMY_PEER = 0x00000400, }; /**