Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Intel MIC Platform Software Stack (MPSS)
  4 *
  5 * Copyright(c) 2014 Intel Corporation.
  6 *
  7 * Intel SCIF driver.
  8 */
  9#ifndef SCIF_MAP_H
 10#define SCIF_MAP_H
 11
 12#include "../bus/scif_bus.h"
 13
 14static __always_inline void *
 15scif_alloc_coherent(dma_addr_t *dma_handle,
 16		    struct scif_dev *scifdev, size_t size,
 17		    gfp_t gfp)
 18{
 19	void *va;
 20
 21	if (scifdev_self(scifdev)) {
 22		va = kmalloc(size, gfp);
 23		if (va)
 24			*dma_handle = virt_to_phys(va);
 25	} else {
 26		va = dma_alloc_coherent(&scifdev->sdev->dev,
 27					size, dma_handle, gfp);
 28		if (va && scifdev_is_p2p(scifdev))
 29			*dma_handle = *dma_handle + scifdev->base_addr;
 30	}
 31	return va;
 32}
 33
 34static __always_inline void
 35scif_free_coherent(void *va, dma_addr_t local,
 36		   struct scif_dev *scifdev, size_t size)
 37{
 38	if (scifdev_self(scifdev)) {
 39		kfree(va);
 40	} else {
 41		if (scifdev_is_p2p(scifdev) && local > scifdev->base_addr)
 42			local = local - scifdev->base_addr;
 43		dma_free_coherent(&scifdev->sdev->dev,
 44				  size, va, local);
 45	}
 46}
 47
 48static __always_inline int
 49scif_map_single(dma_addr_t *dma_handle,
 50		void *local, struct scif_dev *scifdev, size_t size)
 51{
 52	int err = 0;
 53
 54	if (scifdev_self(scifdev)) {
 55		*dma_handle = virt_to_phys((local));
 56	} else {
 57		*dma_handle = dma_map_single(&scifdev->sdev->dev,
 58					     local, size, DMA_BIDIRECTIONAL);
 59		if (dma_mapping_error(&scifdev->sdev->dev, *dma_handle))
 60			err = -ENOMEM;
 61		else if (scifdev_is_p2p(scifdev))
 62			*dma_handle = *dma_handle + scifdev->base_addr;
 63	}
 64	if (err)
 65		*dma_handle = 0;
 66	return err;
 67}
 68
 69static __always_inline void
 70scif_unmap_single(dma_addr_t local, struct scif_dev *scifdev,
 71		  size_t size)
 72{
 73	if (!scifdev_self(scifdev)) {
 74		if (scifdev_is_p2p(scifdev))
 75			local = local - scifdev->base_addr;
 76		dma_unmap_single(&scifdev->sdev->dev, local,
 77				 size, DMA_BIDIRECTIONAL);
 78	}
 79}
 80
 81static __always_inline void *
 82scif_ioremap(dma_addr_t phys, size_t size, struct scif_dev *scifdev)
 83{
 84	void *out_virt;
 85	struct scif_hw_dev *sdev = scifdev->sdev;
 86
 87	if (scifdev_self(scifdev))
 88		out_virt = phys_to_virt(phys);
 89	else
 90		out_virt = (void __force *)
 91			   sdev->hw_ops->remap(sdev, phys, size);
 92	return out_virt;
 93}
 94
 95static __always_inline void
 96scif_iounmap(void *virt, size_t len, struct scif_dev *scifdev)
 97{
 98	if (!scifdev_self(scifdev)) {
 99		struct scif_hw_dev *sdev = scifdev->sdev;
100
101		sdev->hw_ops->unmap(sdev, (void __force __iomem *)virt);
102	}
103}
104
105static __always_inline int
106scif_map_page(dma_addr_t *dma_handle, struct page *page,
107	      struct scif_dev *scifdev)
108{
109	int err = 0;
110
111	if (scifdev_self(scifdev)) {
112		*dma_handle = page_to_phys(page);
113	} else {
114		struct scif_hw_dev *sdev = scifdev->sdev;
115		*dma_handle = dma_map_page(&sdev->dev,
116					   page, 0x0, PAGE_SIZE,
117					   DMA_BIDIRECTIONAL);
118		if (dma_mapping_error(&sdev->dev, *dma_handle))
119			err = -ENOMEM;
120		else if (scifdev_is_p2p(scifdev))
121			*dma_handle = *dma_handle + scifdev->base_addr;
122	}
123	if (err)
124		*dma_handle = 0;
125	return err;
126}
127#endif  /* SCIF_MAP_H */