#define DCSR_CMPST BIT(10) /* The Descriptor Compare Status */
#define DCSR_EORINTR BIT(9) /* The end of Receive */
-#define DRCMR(n) ((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
+#define DRCMR_BASE 0x0100
+#define DRCMR_EXT_BASE_DEFAULT 0x1100
+#define DRCMR_REQ_LIMIT 64
#define DRCMR_MAPVLD BIT(7) /* Map Valid (read / write) */
#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
* @run_bits: Control bits in DCSR register for channel start/stop
* @dma_width: DMA addressing width in bits (32 or 64). Determines the
* DMA mask capability of the controller hardware.
+ * @drcmr_ext_base: Base DRCMR address for extended requests
*/
struct mmp_pdma_ops {
/* Hardware Register Operations */
/* Controller Configuration */
u32 run_bits;
u32 dma_width;
+ u32 drcmr_ext_base;
};
struct mmp_pdma_device {
#define to_mmp_pdma_dev(dmadev) \
container_of(dmadev, struct mmp_pdma_device, device)
+static u32 mmp_pdma_get_drcmr(struct mmp_pdma_device *pdev, u32 drcmr)
+{
+ if (drcmr < DRCMR_REQ_LIMIT)
+ return DRCMR_BASE + (drcmr << 2);
+ return pdev->ops->drcmr_ext_base + ((drcmr - DRCMR_REQ_LIMIT) << 2);
+}
+
/* For 32-bit PDMA */
static void write_next_addr_32(struct mmp_pdma_phy *phy, dma_addr_t addr)
{
pdev = to_mmp_pdma_dev(phy->vchan->chan.device);
- reg = DRCMR(phy->vchan->drcmr);
+ reg = mmp_pdma_get_drcmr(pdev, phy->vchan->drcmr);
writel(DRCMR_MAPVLD | phy->idx, phy->base + reg);
dalgn = readl(phy->base + DALGN);
return;
/* clear the channel mapping in DRCMR */
- reg = DRCMR(pchan->drcmr);
+ reg = mmp_pdma_get_drcmr(pdev, pchan->drcmr);
writel(0, pchan->phy->base + reg);
spin_lock_irqsave(&pdev->phy_lock, flags);
.get_desc_dst_addr = get_desc_dst_addr_32,
.run_bits = (DCSR_RUN),
.dma_width = 32,
+ .drcmr_ext_base = DRCMR_EXT_BASE_DEFAULT,
};
static const struct mmp_pdma_ops spacemit_k1_pdma_ops = {
.get_desc_dst_addr = get_desc_dst_addr_64,
.run_bits = (DCSR_RUN | DCSR_LPAEEN),
.dma_width = 64,
+ .drcmr_ext_base = DRCMR_EXT_BASE_DEFAULT,
};
static const struct of_device_id mmp_pdma_dt_ids[] = {