Commit a10d648d authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Marek Szyprowski
Browse files

powerpc: Convert to physical address DMA mapping



Adapt PowerPC DMA to use physical addresses in order to prepare code
to removal .map_page and .unmap_page.

Signed-off-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20251015-remove-map-page-v5-10-3bbfe3a25cdf@kernel.org
parent 96ddf2ef
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -274,12 +274,12 @@ extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
				  unsigned long mask, gfp_t flag, int node);
extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
				void *vaddr, dma_addr_t dma_handle);
extern dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
				 struct page *page, unsigned long offset,
				 size_t size, unsigned long mask,
extern dma_addr_t iommu_map_phys(struct device *dev, struct iommu_table *tbl,
				 phys_addr_t phys, size_t size,
				 unsigned long mask,
				 enum dma_data_direction direction,
				 unsigned long attrs);
extern void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle,
extern void iommu_unmap_phys(struct iommu_table *tbl, dma_addr_t dma_handle,
			     size_t size, enum dma_data_direction direction,
			     unsigned long attrs);

+10 −12
Original line number Diff line number Diff line
@@ -93,28 +93,26 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size,

/* Creates TCEs for a user provided buffer.  The user buffer must be
 * contiguous real kernel storage (not vmalloc).  The address passed here
 * comprises a page address and offset into that page. The dma_addr_t
 * returned will point to the same byte within the page as was passed in.
 * is a physical address to that page. The dma_addr_t returned will point
 * to the same byte within the page as was passed in.
 */
static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page,
				     unsigned long offset, size_t size,
static dma_addr_t dma_iommu_map_phys(struct device *dev, phys_addr_t phys,
				     size_t size,
				     enum dma_data_direction direction,
				     unsigned long attrs)
{
	return iommu_map_page(dev, get_iommu_table_base(dev), page, offset,
			      size, dma_get_mask(dev), direction, attrs);
	return iommu_map_phys(dev, get_iommu_table_base(dev), phys, size,
			      dma_get_mask(dev), direction, attrs);
}


static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
static void dma_iommu_unmap_phys(struct device *dev, dma_addr_t dma_handle,
				 size_t size, enum dma_data_direction direction,
				 unsigned long attrs)
{
	iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction,
	iommu_unmap_phys(get_iommu_table_base(dev), dma_handle, size, direction,
			 attrs);
}


static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
			    int nelems, enum dma_data_direction direction,
			    unsigned long attrs)
@@ -211,8 +209,8 @@ const struct dma_map_ops dma_iommu_ops = {
	.map_sg			= dma_iommu_map_sg,
	.unmap_sg		= dma_iommu_unmap_sg,
	.dma_supported		= dma_iommu_dma_supported,
	.map_page		= dma_iommu_map_page,
	.unmap_page		= dma_iommu_unmap_page,
	.map_phys		= dma_iommu_map_phys,
	.unmap_phys		= dma_iommu_unmap_phys,
	.get_required_mask	= dma_iommu_get_required_mask,
	.mmap			= dma_common_mmap,
	.get_sgtable		= dma_common_get_sgtable,
+7 −7
Original line number Diff line number Diff line
@@ -848,12 +848,12 @@ EXPORT_SYMBOL_GPL(iommu_tce_table_put);

/* Creates TCEs for a user provided buffer.  The user buffer must be
 * contiguous real kernel storage (not vmalloc).  The address passed here
 * comprises a page address and offset into that page. The dma_addr_t
 * returned will point to the same byte within the page as was passed in.
 * is physical address into that page. The dma_addr_t returned will point
 * to the same byte within the page as was passed in.
 */
dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
			  struct page *page, unsigned long offset, size_t size,
			  unsigned long mask, enum dma_data_direction direction,
dma_addr_t iommu_map_phys(struct device *dev, struct iommu_table *tbl,
			  phys_addr_t phys, size_t size, unsigned long mask,
			  enum dma_data_direction direction,
			  unsigned long attrs)
{
	dma_addr_t dma_handle = DMA_MAPPING_ERROR;
@@ -863,7 +863,7 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,

	BUG_ON(direction == DMA_NONE);

	vaddr = page_address(page) + offset;
	vaddr = phys_to_virt(phys);
	uaddr = (unsigned long)vaddr;

	if (tbl) {
@@ -890,7 +890,7 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
	return dma_handle;
}

void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle,
void iommu_unmap_phys(struct iommu_table *tbl, dma_addr_t dma_handle,
		      size_t size, enum dma_data_direction direction,
		      unsigned long attrs)
{
+19 −14
Original line number Diff line number Diff line
@@ -551,18 +551,20 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,

/* Creates TCEs for a user provided buffer.  The user buffer must be
 * contiguous real kernel storage (not vmalloc).  The address passed here
 * comprises a page address and offset into that page. The dma_addr_t
 * returned will point to the same byte within the page as was passed in.
 * is physical address to that hat page. The dma_addr_t returned will point
 * to the same byte within the page as was passed in.
 */

static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
	unsigned long offset, size_t size, enum dma_data_direction direction,
	unsigned long attrs)
static dma_addr_t ps3_sb_map_phys(struct device *_dev, phys_addr_t phys,
	size_t size, enum dma_data_direction direction, unsigned long attrs)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
	int result;
	dma_addr_t bus_addr;
	void *ptr = page_address(page) + offset;
	void *ptr = phys_to_virt(phys);

	if (unlikely(attrs & DMA_ATTR_MMIO))
		return DMA_MAPPING_ERROR;

	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
			     &bus_addr,
@@ -577,8 +579,8 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
	return bus_addr;
}

static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
				    unsigned long offset, size_t size,
static dma_addr_t ps3_ioc0_map_phys(struct device *_dev, phys_addr_t phys,
				    size_t size,
				    enum dma_data_direction direction,
				    unsigned long attrs)
{
@@ -586,7 +588,10 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
	int result;
	dma_addr_t bus_addr;
	u64 iopte_flag;
	void *ptr = page_address(page) + offset;
	void *ptr = phys_to_virt(phys);

	if (unlikely(attrs & DMA_ATTR_MMIO))
		return DMA_MAPPING_ERROR;

	iopte_flag = CBE_IOPTE_M;
	switch (direction) {
@@ -613,7 +618,7 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
	return bus_addr;
}

static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr,
static void ps3_unmap_phys(struct device *_dev, dma_addr_t dma_addr,
	size_t size, enum dma_data_direction direction, unsigned long attrs)
{
	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
@@ -690,8 +695,8 @@ static const struct dma_map_ops ps3_sb_dma_ops = {
	.map_sg = ps3_sb_map_sg,
	.unmap_sg = ps3_sb_unmap_sg,
	.dma_supported = ps3_dma_supported,
	.map_page = ps3_sb_map_page,
	.unmap_page = ps3_unmap_page,
	.map_phys = ps3_sb_map_phys,
	.unmap_phys = ps3_unmap_phys,
	.mmap = dma_common_mmap,
	.get_sgtable = dma_common_get_sgtable,
	.alloc_pages_op = dma_common_alloc_pages,
@@ -704,8 +709,8 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
	.map_sg = ps3_ioc0_map_sg,
	.unmap_sg = ps3_ioc0_unmap_sg,
	.dma_supported = ps3_dma_supported,
	.map_page = ps3_ioc0_map_page,
	.unmap_page = ps3_unmap_page,
	.map_phys = ps3_ioc0_map_phys,
	.unmap_phys = ps3_unmap_phys,
	.mmap = dma_common_mmap,
	.get_sgtable = dma_common_get_sgtable,
	.alloc_pages_op = dma_common_alloc_pages,
+8 −7
Original line number Diff line number Diff line
@@ -86,17 +86,18 @@ static void ibmebus_free_coherent(struct device *dev,
	kfree(vaddr);
}

static dma_addr_t ibmebus_map_page(struct device *dev,
				   struct page *page,
				   unsigned long offset,
static dma_addr_t ibmebus_map_phys(struct device *dev, phys_addr_t phys,
				   size_t size,
				   enum dma_data_direction direction,
				   unsigned long attrs)
{
	return (dma_addr_t)(page_address(page) + offset);
	if (attrs & DMA_ATTR_MMIO)
		return DMA_MAPPING_ERROR;

	return (dma_addr_t)(phys_to_virt(phys));
}

static void ibmebus_unmap_page(struct device *dev,
static void ibmebus_unmap_phys(struct device *dev,
			       dma_addr_t dma_addr,
			       size_t size,
			       enum dma_data_direction direction,
@@ -146,8 +147,8 @@ static const struct dma_map_ops ibmebus_dma_ops = {
	.unmap_sg           = ibmebus_unmap_sg,
	.dma_supported      = ibmebus_dma_supported,
	.get_required_mask  = ibmebus_dma_get_required_mask,
	.map_page           = ibmebus_map_page,
	.unmap_page         = ibmebus_unmap_page,
	.map_phys           = ibmebus_map_phys,
	.unmap_phys         = ibmebus_unmap_phys,
};

static int ibmebus_match_path(struct device *dev, const void *data)
Loading