Commit 9fb0f9ac authored by Steve Lin's avatar Steve Lin Committed by Jassi Brar

mailbox: bcm-pdc: Changes so mbox client can be removed / re-inserted

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: default avatarSteve Lin <steven.lin1@broadcom.com>
Signed-off-by: default avatarRob Rice <rob.rice@broadcom.com>
Reviewed-by: default avatarAndy Gospodarek <gospo@broadcom.com>
Signed-off-by: default avatarJassi Brar <jaswinder.singh@linaro.org>
parent 9b1b2b3a
...@@ -117,15 +117,16 @@ ...@@ -117,15 +117,16 @@
/* /*
* Sets the following bits for write to transmit control reg: * Sets the following bits for write to transmit control reg:
* 0 - XmtEn - enable activity on the tx channel
* 11 - PtyChkDisable - parity check is disabled * 11 - PtyChkDisable - parity check is disabled
* 20:18 - BurstLen = 3 -> 2^7 = 128 byte data reads from memory * 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: * 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 * 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 * 9 - SepRxHdrDescEn - place start of new frames only in descriptors
* that have StartOfFrame set * that have StartOfFrame set
...@@ -135,7 +136,10 @@ ...@@ -135,7 +136,10 @@
* 11 - PtyChkDisable - parity check is disabled * 11 - PtyChkDisable - parity check is disabled
* 20:18 - BurstLen = 3 -> 2^7 = 128 byte data reads from memory * 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) #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) ...@@ -1054,6 +1058,15 @@ static int pdc_ring_init(struct pdc_state *pdcs, int ringset)
/* Tell device the base DMA address of each ring */ /* Tell device the base DMA address of each ring */
dma_reg = &pdcs->regs->dmaregs[ringset]; 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), iowrite32(lower_32_bits(pdcs->tx_ring_alloc.dmabase),
(void *)&dma_reg->dmaxmt.addrlow); (void *)&dma_reg->dmaxmt.addrlow);
iowrite32(upper_32_bits(pdcs->tx_ring_alloc.dmabase), iowrite32(upper_32_bits(pdcs->tx_ring_alloc.dmabase),
...@@ -1064,6 +1077,11 @@ static int pdc_ring_init(struct pdc_state *pdcs, int ringset) ...@@ -1064,6 +1077,11 @@ static int pdc_ring_init(struct pdc_state *pdcs, int ringset)
iowrite32(upper_32_bits(pdcs->rx_ring_alloc.dmabase), iowrite32(upper_32_bits(pdcs->rx_ring_alloc.dmabase),
(void *)&dma_reg->dmarcv.addrhigh); (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 */ /* Initialize descriptors */
for (i = 0; i < PDC_RING_ENTRIES; i++) { for (i = 0; i < PDC_RING_ENTRIES; i++) {
/* Every tx descriptor can be used for start of frame. */ /* Every tx descriptor can be used for start of frame. */
...@@ -1235,22 +1253,40 @@ void pdc_hw_init(struct pdc_state *pdcs) ...@@ -1235,22 +1253,40 @@ void pdc_hw_init(struct pdc_state *pdcs)
pdcs->nrxd = PDC_RING_ENTRIES; pdcs->nrxd = PDC_RING_ENTRIES;
pdcs->ntxpost = PDC_RING_ENTRIES - 1; pdcs->ntxpost = PDC_RING_ENTRIES - 1;
pdcs->nrxpost = 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]; 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), iowrite32(PDC_RX_CTL + (pdcs->rx_status_len << 1),
(void *)&dma_reg->dmarcv.control); (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) if (pdcs->pdc_resp_hdr_len == PDC_SPU2_RESP_HDR_LEN)
iowrite32(PDC_CKSUM_CTRL, iowrite32(PDC_CKSUM_CTRL,
pdcs->pdc_reg_vbase + PDC_CKSUM_CTRL_OFFSET); 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 * pdc_rx_buf_pool_create() - Pool of receive buffers used to catch the metadata
* header returned with each response message. * header returned with each response message.
...@@ -1505,6 +1541,8 @@ static int pdc_remove(struct platform_device *pdev) ...@@ -1505,6 +1541,8 @@ static int pdc_remove(struct platform_device *pdev)
pdc_free_debugfs(); pdc_free_debugfs();
pdc_hw_disable(pdcs);
mbox_controller_unregister(&pdcs->mbc); mbox_controller_unregister(&pdcs->mbc);
dma_pool_destroy(pdcs->rx_buf_pool); dma_pool_destroy(pdcs->rx_buf_pool);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment