162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_ARM_DMA_H
362306a36Sopenharmony_ci#define __ASM_ARM_DMA_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * This is the maximum virtual address which can be DMA'd from.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#ifndef CONFIG_ZONE_DMA
962306a36Sopenharmony_ci#define MAX_DMA_ADDRESS	0xffffffffUL
1062306a36Sopenharmony_ci#else
1162306a36Sopenharmony_ci#define MAX_DMA_ADDRESS	({ \
1262306a36Sopenharmony_ci	extern phys_addr_t arm_dma_zone_size; \
1362306a36Sopenharmony_ci	arm_dma_zone_size && arm_dma_zone_size < (0x100000000ULL - PAGE_OFFSET) ? \
1462306a36Sopenharmony_ci		(PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; })
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciextern phys_addr_t arm_dma_limit;
1762306a36Sopenharmony_ci#define ARCH_LOW_ADDRESS_LIMIT arm_dma_limit
1862306a36Sopenharmony_ci#endif
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#ifdef CONFIG_ISA_DMA_API
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * This is used to support drivers written for the x86 ISA DMA API.
2362306a36Sopenharmony_ci * It should not be re-used except for that purpose.
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_ci#include <linux/spinlock.h>
2662306a36Sopenharmony_ci#include <linux/scatterlist.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include <mach/isa-dma.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/*
3162306a36Sopenharmony_ci * The DMA modes reflect the settings for the ISA DMA controller
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci#define DMA_MODE_MASK	 0xcc
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define DMA_MODE_READ	 0x44
3662306a36Sopenharmony_ci#define DMA_MODE_WRITE	 0x48
3762306a36Sopenharmony_ci#define DMA_MODE_CASCADE 0xc0
3862306a36Sopenharmony_ci#define DMA_AUTOINIT	 0x10
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciextern raw_spinlock_t  dma_spin_lock;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic inline unsigned long claim_dma_lock(void)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	unsigned long flags;
4562306a36Sopenharmony_ci	raw_spin_lock_irqsave(&dma_spin_lock, flags);
4662306a36Sopenharmony_ci	return flags;
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic inline void release_dma_lock(unsigned long flags)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	raw_spin_unlock_irqrestore(&dma_spin_lock, flags);
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* Clear the 'DMA Pointer Flip Flop'.
5562306a36Sopenharmony_ci * Write 0 for LSB/MSB, 1 for MSB/LSB access.
5662306a36Sopenharmony_ci */
5762306a36Sopenharmony_ci#define clear_dma_ff(chan)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/* Set only the page register bits of the transfer address.
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * NOTE: This is an architecture specific function, and should
6262306a36Sopenharmony_ci *       be hidden from the drivers
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_ciextern void set_dma_page(unsigned int chan, char pagenr);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* Request a DMA channel
6762306a36Sopenharmony_ci *
6862306a36Sopenharmony_ci * Some architectures may need to do allocate an interrupt
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_ciextern int  request_dma(unsigned int chan, const char * device_id);
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* Free a DMA channel
7362306a36Sopenharmony_ci *
7462306a36Sopenharmony_ci * Some architectures may need to do free an interrupt
7562306a36Sopenharmony_ci */
7662306a36Sopenharmony_ciextern void free_dma(unsigned int chan);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* Enable DMA for this channel
7962306a36Sopenharmony_ci *
8062306a36Sopenharmony_ci * On some architectures, this may have other side effects like
8162306a36Sopenharmony_ci * enabling an interrupt and setting the DMA registers.
8262306a36Sopenharmony_ci */
8362306a36Sopenharmony_ciextern void enable_dma(unsigned int chan);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/* Disable DMA for this channel
8662306a36Sopenharmony_ci *
8762306a36Sopenharmony_ci * On some architectures, this may have other side effects like
8862306a36Sopenharmony_ci * disabling an interrupt or whatever.
8962306a36Sopenharmony_ci */
9062306a36Sopenharmony_ciextern void disable_dma(unsigned int chan);
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* Test whether the specified channel has an active DMA transfer
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_ciextern int dma_channel_active(unsigned int chan);
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/* Set the DMA scatter gather list for this channel
9762306a36Sopenharmony_ci *
9862306a36Sopenharmony_ci * This should not be called if a DMA channel is enabled,
9962306a36Sopenharmony_ci * especially since some DMA architectures don't update the
10062306a36Sopenharmony_ci * DMA address immediately, but defer it to the enable_dma().
10162306a36Sopenharmony_ci */
10262306a36Sopenharmony_ciextern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/* Set the DMA address for this channel
10562306a36Sopenharmony_ci *
10662306a36Sopenharmony_ci * This should not be called if a DMA channel is enabled,
10762306a36Sopenharmony_ci * especially since some DMA architectures don't update the
10862306a36Sopenharmony_ci * DMA address immediately, but defer it to the enable_dma().
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_ciextern void __set_dma_addr(unsigned int chan, void *addr);
11162306a36Sopenharmony_ci#define set_dma_addr(chan, addr)				\
11262306a36Sopenharmony_ci	__set_dma_addr(chan, (void *)isa_bus_to_virt(addr))
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/* Set the DMA byte count for this channel
11562306a36Sopenharmony_ci *
11662306a36Sopenharmony_ci * This should not be called if a DMA channel is enabled,
11762306a36Sopenharmony_ci * especially since some DMA architectures don't update the
11862306a36Sopenharmony_ci * DMA count immediately, but defer it to the enable_dma().
11962306a36Sopenharmony_ci */
12062306a36Sopenharmony_ciextern void set_dma_count(unsigned int chan, unsigned long count);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/* Set the transfer direction for this channel
12362306a36Sopenharmony_ci *
12462306a36Sopenharmony_ci * This should not be called if a DMA channel is enabled,
12562306a36Sopenharmony_ci * especially since some DMA architectures don't update the
12662306a36Sopenharmony_ci * DMA transfer direction immediately, but defer it to the
12762306a36Sopenharmony_ci * enable_dma().
12862306a36Sopenharmony_ci */
12962306a36Sopenharmony_ciextern void set_dma_mode(unsigned int chan, unsigned int mode);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci/* Set the transfer speed for this channel
13262306a36Sopenharmony_ci */
13362306a36Sopenharmony_ciextern void set_dma_speed(unsigned int chan, int cycle_ns);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/* Get DMA residue count. After a DMA transfer, this
13662306a36Sopenharmony_ci * should return zero. Reading this while a DMA transfer is
13762306a36Sopenharmony_ci * still in progress will return unpredictable results.
13862306a36Sopenharmony_ci * If called before the channel has been used, it may return 1.
13962306a36Sopenharmony_ci * Otherwise, it returns the number of _bytes_ left to transfer.
14062306a36Sopenharmony_ci */
14162306a36Sopenharmony_ciextern int  get_dma_residue(unsigned int chan);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#ifndef NO_DMA
14462306a36Sopenharmony_ci#define NO_DMA	255
14562306a36Sopenharmony_ci#endif
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci#endif /* CONFIG_ISA_DMA_API */
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#endif /* __ASM_ARM_DMA_H */
150