drivers/dma/sun6i-dma.c

Source file repositories/reference/linux-study-clean/drivers/dma/sun6i-dma.c

File Facts

System
Linux kernel
Corpus path
drivers/dma/sun6i-dma.c
Extension
.c
Size
42361 bytes
Lines
1528
Domain
Driver Families
Bucket
drivers/dma
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sun6i_dma_config {
	u32 nr_max_channels;
	u32 nr_max_requests;
	u32 nr_max_vchans;
	/*
	 * In the datasheets/user manuals of newer Allwinner SoCs, a special
	 * bit (bit 2 at register 0x20) is present.
	 * It's named "DMA MCLK interface circuit auto gating bit" in the
	 * documents, and the footnote of this register says that this bit
	 * should be set up when initializing the DMA controller.
	 * Allwinner A23/A33 user manuals do not have this bit documented,
	 * however these SoCs really have and need this bit, as seen in the
	 * BSP kernel source code.
	 */
	void (*clock_autogate_enable)(struct sun6i_dma_dev *);
	void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
	void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq);
	void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode);
	u32 src_burst_lengths;
	u32 dst_burst_lengths;
	u32 src_addr_widths;
	u32 dst_addr_widths;
	bool has_high_addr;
	bool has_mbus_clk;
};

/*
 * Hardware representation of the LLI
 *
 * The hardware will be fed the physical address of this structure,
 * and read its content in order to start the transfer.
 */
struct sun6i_dma_lli {
	u32			cfg;
	u32			src;
	u32			dst;
	u32			len;
	u32			para;
	u32			p_lli_next;

	/*
	 * This field is not used by the DMA controller, but will be
	 * used by the CPU to go through the list (mostly for dumping
	 * or freeing it).
	 */
	struct sun6i_dma_lli	*v_lli_next;
};


struct sun6i_desc {
	struct virt_dma_desc	vd;
	dma_addr_t		p_lli;
	struct sun6i_dma_lli	*v_lli;
};

struct sun6i_pchan {
	u32			idx;
	void __iomem		*base;
	struct sun6i_vchan	*vchan;
	struct sun6i_desc	*desc;
	struct sun6i_desc	*done;
};

struct sun6i_vchan {
	struct virt_dma_chan	vc;
	struct list_head	node;
	struct dma_slave_config	cfg;
	struct sun6i_pchan	*phy;
	u8			port;
	u8			irq_type;
	bool			cyclic;
};

struct sun6i_dma_dev {
	struct dma_device	slave;
	void __iomem		*base;
	struct clk		*clk;
	struct clk		*clk_mbus;
	int			irq;
	spinlock_t		lock;
	struct reset_control	*rstc;
	struct tasklet_struct	task;
	atomic_t		tasklet_shutdown;
	struct list_head	pending;
	struct dma_pool		*pool;
	struct sun6i_pchan	*pchans;
	struct sun6i_vchan	*vchans;
	const struct sun6i_dma_config *cfg;
	u32			num_pchans;
	u32			num_vchans;

Annotation

Implementation Notes