Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935362AbcKNS1D (ORCPT ); Mon, 14 Nov 2016 13:27:03 -0500 Received: from mail-pg0-f45.google.com ([74.125.83.45]:35115 "EHLO mail-pg0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752723AbcKNS1C (ORCPT ); Mon, 14 Nov 2016 13:27:02 -0500 From: Rob Rice To: Jassi Brar Cc: bcm-kernel-feedback-list@broadcom.com, linux-kernel@vger.kernel.org, Steve Lin , Rob Rice Subject: [PATCH 02/11] mailbox: bcm-pdc: Changes so mbox client can be removed / re-inserted Date: Mon, 14 Nov 2016 13:25:56 -0500 Message-Id: <1479147965-29662-3-git-send-email-rob.rice@broadcom.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1479147965-29662-1-git-send-email-rob.rice@broadcom.com> References: <1479147965-29662-1-git-send-email-rob.rice@broadcom.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4817 Lines: 135 From: Steve Lin Ensure that DMA is disabled, and pointers reset, when changing DMA base addresses in pdc_ring_init(). This allows a mailbox client to be re-inserted after being removed. Otherwise, the DMA doesn't restart so the client hangs while being reinserted. Signed-off-by: Steve Lin Signed-off-by: Rob Rice Reviewed-by: Andy Gospodarek --- drivers/mailbox/bcm-pdc-mailbox.c | 54 +++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c index a9c804f..3b4ebbe 100644 --- a/drivers/mailbox/bcm-pdc-mailbox.c +++ b/drivers/mailbox/bcm-pdc-mailbox.c @@ -117,15 +117,16 @@ /* * Sets the following bits for write to transmit control reg: - * 0 - XmtEn - enable activity on the tx channel * 11 - PtyChkDisable - parity check is disabled * 20:18 - BurstLen = 3 -> 2^7 = 128 byte data reads from memory */ -#define PDC_TX_CTL 0x000C0801 +#define PDC_TX_CTL 0x000C0800 + +/* Bit in tx control reg to enable tx channel */ +#define PDC_TX_ENABLE 0x1 /* * Sets the following bits for write to receive control reg: - * 0 - RcvEn - enable activity on the rx channel * 7:1 - RcvOffset - size in bytes of status region at start of rx frame buf * 9 - SepRxHdrDescEn - place start of new frames only in descriptors * that have StartOfFrame set @@ -135,7 +136,10 @@ * 11 - PtyChkDisable - parity check is disabled * 20:18 - BurstLen = 3 -> 2^7 = 128 byte data reads from memory */ -#define PDC_RX_CTL 0x000C0E01 +#define PDC_RX_CTL 0x000C0E00 + +/* Bit in rx control reg to enable rx channel */ +#define PDC_RX_ENABLE 0x1 #define CRYPTO_D64_RS0_CD_MASK ((PDC_RING_ENTRIES * RING_ENTRY_SIZE) - 1) @@ -1054,6 +1058,15 @@ static int pdc_ring_init(struct pdc_state *pdcs, int ringset) /* Tell device the base DMA address of each ring */ dma_reg = &pdcs->regs->dmaregs[ringset]; + + /* But first disable DMA and set curptr to 0 for both TX & RX */ + iowrite32(PDC_TX_CTL, &dma_reg->dmaxmt.control); + iowrite32((PDC_RX_CTL + (pdcs->rx_status_len << 1)), + (void *)&dma_reg->dmarcv.control); + iowrite32(0, (void *)&dma_reg->dmaxmt.ptr); + iowrite32(0, (void *)&dma_reg->dmarcv.ptr); + + /* Set base DMA addresses */ iowrite32(lower_32_bits(pdcs->tx_ring_alloc.dmabase), (void *)&dma_reg->dmaxmt.addrlow); iowrite32(upper_32_bits(pdcs->tx_ring_alloc.dmabase), @@ -1064,6 +1077,11 @@ static int pdc_ring_init(struct pdc_state *pdcs, int ringset) iowrite32(upper_32_bits(pdcs->rx_ring_alloc.dmabase), (void *)&dma_reg->dmarcv.addrhigh); + /* Re-enable DMA */ + iowrite32(PDC_TX_CTL | PDC_TX_ENABLE, &dma_reg->dmaxmt.control); + iowrite32((PDC_RX_CTL | PDC_RX_ENABLE | (pdcs->rx_status_len << 1)), + (void *)&dma_reg->dmarcv.control); + /* Initialize descriptors */ for (i = 0; i < PDC_RING_ENTRIES; i++) { /* Every tx descriptor can be used for start of frame. */ @@ -1235,23 +1253,41 @@ void pdc_hw_init(struct pdc_state *pdcs) pdcs->nrxd = PDC_RING_ENTRIES; pdcs->ntxpost = PDC_RING_ENTRIES - 1; pdcs->nrxpost = PDC_RING_ENTRIES - 1; - pdcs->regs->intmask = 0; + iowrite32(0, &pdcs->regs->intmask); dma_reg = &pdcs->regs->dmaregs[ringset]; - iowrite32(0, (void *)&dma_reg->dmaxmt.ptr); - iowrite32(0, (void *)&dma_reg->dmarcv.ptr); - iowrite32(PDC_TX_CTL, (void *)&dma_reg->dmaxmt.control); + /* Configure DMA but will enable later in pdc_ring_init() */ + iowrite32(PDC_TX_CTL, &dma_reg->dmaxmt.control); iowrite32(PDC_RX_CTL + (pdcs->rx_status_len << 1), (void *)&dma_reg->dmarcv.control); + /* Reset current index pointers after making sure DMA is disabled */ + iowrite32(0, &dma_reg->dmaxmt.ptr); + iowrite32(0, &dma_reg->dmarcv.ptr); + if (pdcs->pdc_resp_hdr_len == PDC_SPU2_RESP_HDR_LEN) iowrite32(PDC_CKSUM_CTRL, pdcs->pdc_reg_vbase + PDC_CKSUM_CTRL_OFFSET); } /** + * pdc_hw_disable() - Disable the tx and rx control in the hw. + * @pdcs: PDC state structure + * + */ +static void pdc_hw_disable(struct pdc_state *pdcs) +{ + struct dma64 *dma_reg; + + dma_reg = &pdcs->regs->dmaregs[PDC_RINGSET]; + iowrite32(PDC_TX_CTL, &dma_reg->dmaxmt.control); + iowrite32(PDC_RX_CTL + (pdcs->rx_status_len << 1), + &dma_reg->dmarcv.control); +} + +/** * pdc_rx_buf_pool_create() - Pool of receive buffers used to catch the metadata * header returned with each response message. * @pdcs: PDC state structure @@ -1505,6 +1541,8 @@ static int pdc_remove(struct platform_device *pdev) pdc_free_debugfs(); + pdc_hw_disable(pdcs); + mbox_controller_unregister(&pdcs->mbc); dma_pool_destroy(pdcs->rx_buf_pool); -- 2.1.0