pci: t264: xdma: Fix MSI for local and remote

Use different MSI channels for local and remote use case to avoid
configuring same registers with different info.

Bug 4779415

Change-Id: I13fab912589d47484881cd862fc9eaf0f602e64e
Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-t264/+/3186319
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Tested-by: Bitan Biswas <bbiswas@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Nagarjuna Kristam
2024-08-01 14:20:00 +05:30
committed by Jon Hunter
parent c51582e26e
commit 8774bd321b
2 changed files with 16 additions and 10 deletions

View File

@@ -21,6 +21,7 @@
/* Channel specific registers */ /* Channel specific registers */
#define XDMA_CHANNEL_CTRL 0x2000 #define XDMA_CHANNEL_CTRL 0x2000
#define XDMA_CHANNEL_CTRL_MSI_CHANNEL_NUMBER OSI_GENMASK(11, 9) #define XDMA_CHANNEL_CTRL_MSI_CHANNEL_NUMBER OSI_GENMASK(11, 9)
#define XDMA_CHANNEL_CTRL_MSI_CHANNEL_SHIFT 9
#define XDMA_CHANNEL_CTRL_DMA_CMD_SOURCE OSI_BIT(2) #define XDMA_CHANNEL_CTRL_DMA_CMD_SOURCE OSI_BIT(2)
#define XDMA_CHANNEL_CTRL_DMA_OPERATION OSI_BIT(1) #define XDMA_CHANNEL_CTRL_DMA_OPERATION OSI_BIT(1)
#define XDMA_CHANNEL_CTRL_EN OSI_BIT(0) #define XDMA_CHANNEL_CTRL_EN OSI_BIT(0)

View File

@@ -71,12 +71,13 @@ static inline void xdma_ll_ch_init(void __iomem *xdma_base, uint8_t ch, dma_addr
{ {
uint32_t val; uint32_t val;
/* All channels mapped to same MSI. */
val = XDMA_CHANNEL_CTRL_EN; val = XDMA_CHANNEL_CTRL_EN;
if (rw_type) if (rw_type)
val |= XDMA_CHANNEL_CTRL_DMA_OPERATION; val |= XDMA_CHANNEL_CTRL_DMA_OPERATION;
else else
val &= ~XDMA_CHANNEL_CTRL_DMA_OPERATION; val &= ~XDMA_CHANNEL_CTRL_DMA_OPERATION;
/* All local channels mapped to same MSI and all remote mapped to same MSI */
val |= (is_remote_dma << XDMA_CHANNEL_CTRL_MSI_CHANNEL_SHIFT);
xdma_channel_wr(xdma_base, ch, val, XDMA_CHANNEL_CTRL); xdma_channel_wr(xdma_base, ch, val, XDMA_CHANNEL_CTRL);
} }
@@ -108,10 +109,10 @@ static inline int xdma_ch_init(struct xdma_prv *prv, struct xdma_chan *ch, uint8
XDMA_CHANNEL_DESCRIPTOR_LIST_POINTER_HIGH); XDMA_CHANNEL_DESCRIPTOR_LIST_POINTER_HIGH);
if (prv->is_remote_dma) if (prv->is_remote_dma)
xdma_channel_wr(prv->xdma_base, 0, XDMA_MSI_CHANNEL_CFG_INTR_DESTINATION, xdma_channel_wr(prv->xdma_base, prv->is_remote_dma,
XDMA_MSI_CHANNEL_CFG_INTR); XDMA_MSI_CHANNEL_CFG_INTR_DESTINATION, XDMA_MSI_CHANNEL_CFG_INTR);
else else
xdma_channel_wr(prv->xdma_base, 0, 0, XDMA_MSI_CHANNEL_CFG_INTR); xdma_channel_wr(prv->xdma_base, prv->is_remote_dma, 0, XDMA_MSI_CHANNEL_CFG_INTR);
return 0; return 0;
} }
@@ -246,9 +247,11 @@ static irqreturn_t xdma_irq_handler(int irq, void *cookie)
* resetting, set star_processing & end_processing irrespective of * resetting, set star_processing & end_processing irrespective of
* new_xfer_valid * new_xfer_valid
*/ */
val = xdma_channel_rd(prv->xdma_base, 0, XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS); val = xdma_channel_rd(prv->xdma_base, prv->is_remote_dma,
XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS);
val |= XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS_INTR_START_PROCESSING; val |= XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS_INTR_START_PROCESSING;
xdma_channel_wr(prv->xdma_base, 0, val, XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS); xdma_channel_wr(prv->xdma_base, prv->is_remote_dma, val,
XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (!(prv->ch_init & OSI_BIT(i))) if (!(prv->ch_init & OSI_BIT(i)))
@@ -265,7 +268,7 @@ static irqreturn_t xdma_irq_handler(int irq, void *cookie)
{ {
u32 temp; u32 temp;
temp = xdma_channel_rd(prv->xdma_base, 0, temp = xdma_channel_rd(prv->xdma_base, prv->is_remote_dma,
XDMA_CHANNEL_FUNC_ERROR_STATUS); XDMA_CHANNEL_FUNC_ERROR_STATUS);
} }
@@ -288,9 +291,11 @@ static irqreturn_t xdma_irq_handler(int irq, void *cookie)
} }
} }
val = xdma_channel_rd(prv->xdma_base, 0, XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS); val = xdma_channel_rd(prv->xdma_base, prv->is_remote_dma,
XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS);
val |= XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS_INTR_END_PROCESSING; val |= XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS_INTR_END_PROCESSING;
xdma_channel_wr(prv->xdma_base, 0, val, XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS); xdma_channel_wr(prv->xdma_base, prv->is_remote_dma, val,
XDMA_MSI_CHANNEL_PRIMARY_INTR_STATUS);
/* Must enable before exit */ /* Must enable before exit */
enable_irq((u32)(irq & INT_MAX)); enable_irq((u32)(irq & INT_MAX));
@@ -523,7 +528,7 @@ tegra_pcie_dma_status_t tegra264_pcie_xdma_set_msi(void *cookie, u64 msi_addr, u
XDMA_MSI_CFG_REMOTE_ADDRESS_HI); XDMA_MSI_CFG_REMOTE_ADDRESS_HI);
} }
xdma_channel_wr(prv->xdma_base, 0, msi_data, XDMA_MSI_CHANNEL_CFG_INTR_ID); xdma_channel_wr(prv->xdma_base, prv->is_remote_dma, msi_data, XDMA_MSI_CHANNEL_CFG_INTR_ID);
return TEGRA_PCIE_DMA_SUCCESS; return TEGRA_PCIE_DMA_SUCCESS;
} }