mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 00:39:48 +00:00
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: Steve Lin <steven.lin1@broadcom.com> Signed-off-by: Rob Rice <rob.rice@broadcom.com> Reviewed-by: Andy Gospodarek <gospo@broadcom.com> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
This commit is contained in:
parent
9b1b2b3adb
commit
9fb0f9ac54
1 changed files with 46 additions and 8 deletions
|
@ -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 @@
|
||||||
* 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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue