if (!ring->vaddr_unaligned)
                return;
 
-       if (ring->cached)
+       if (ring->cached) {
+               dma_unmap_single(ab->dev, ring->paddr_unaligned, ring->size,
+                                DMA_FROM_DEVICE);
                kfree(ring->vaddr_unaligned);
-       else
+       } else {
                dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
                                  ring->paddr_unaligned);
+       }
 
        ring->vaddr_unaligned = NULL;
 }
 
                if (cached) {
                        ring->vaddr_unaligned = kzalloc(ring->size, GFP_KERNEL);
-                       ring->paddr_unaligned = virt_to_phys(ring->vaddr_unaligned);
+                       if (!ring->vaddr_unaligned)
+                               return -ENOMEM;
+
+                       ring->paddr_unaligned = dma_map_single(ab->dev,
+                                                              ring->vaddr_unaligned,
+                                                              ring->size,
+                                                              DMA_FROM_DEVICE);
+                       if (dma_mapping_error(ab->dev, ring->paddr_unaligned)) {
+                               kfree(ring->vaddr_unaligned);
+                               ring->vaddr_unaligned = NULL;
+                               return -ENOMEM;
+                       }
                }
        }
 
 
        return NULL;
 }
 
+static u32 *ath11k_hal_srng_dst_peek_with_dma(struct ath11k_base *ab,
+                                             struct hal_srng *srng, dma_addr_t *paddr)
+{
+       lockdep_assert_held(&srng->lock);
+
+       if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) {
+               *paddr = srng->ring_base_paddr +
+                         sizeof(*srng->ring_base_vaddr) * srng->u.dst_ring.tp;
+               return srng->ring_base_vaddr + srng->u.dst_ring.tp;
+       }
+
+       return NULL;
+}
+
 static void ath11k_hal_srng_prefetch_desc(struct ath11k_base *ab,
                                          struct hal_srng *srng)
 {
+       dma_addr_t desc_paddr;
        u32 *desc;
 
        /* prefetch only if desc is available */
-       desc = ath11k_hal_srng_dst_peek(ab, srng);
+       desc = ath11k_hal_srng_dst_peek_with_dma(ab, srng, &desc_paddr);
        if (likely(desc)) {
-               dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc),
+               dma_sync_single_for_cpu(ab->dev, desc_paddr,
                                        (srng->entry_size * sizeof(u32)),
                                        DMA_FROM_DEVICE);
                prefetch(desc);