xref: /OK3568_Linux_fs/u-boot/drivers/dma/lpc32xx_dma.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2008 by NXP Semiconductors
3*4882a593Smuzhiyun  * @Author: Kevin Wells
4*4882a593Smuzhiyun  * @Descr: LPC3250 DMA controller interface support functions
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (c) 2015 Tyco Fire Protection Products.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun #include <errno.h>
13*4882a593Smuzhiyun #include <asm/arch/dma.h>
14*4882a593Smuzhiyun #include <asm/arch/cpu.h>
15*4882a593Smuzhiyun #include <asm/arch/clk.h>
16*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
17*4882a593Smuzhiyun #include <asm/io.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* DMA controller channel register structure */
20*4882a593Smuzhiyun struct dmac_chan_reg {
21*4882a593Smuzhiyun 	u32 src_addr;
22*4882a593Smuzhiyun 	u32 dest_addr;
23*4882a593Smuzhiyun 	u32 lli;
24*4882a593Smuzhiyun 	u32 control;
25*4882a593Smuzhiyun 	u32 config_ch;
26*4882a593Smuzhiyun 	u32 reserved[3];
27*4882a593Smuzhiyun };
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* DMA controller register structures */
30*4882a593Smuzhiyun struct dma_reg {
31*4882a593Smuzhiyun 	u32 int_stat;
32*4882a593Smuzhiyun 	u32 int_tc_stat;
33*4882a593Smuzhiyun 	u32 int_tc_clear;
34*4882a593Smuzhiyun 	u32 int_err_stat;
35*4882a593Smuzhiyun 	u32 int_err_clear;
36*4882a593Smuzhiyun 	u32 raw_tc_stat;
37*4882a593Smuzhiyun 	u32 raw_err_stat;
38*4882a593Smuzhiyun 	u32 chan_enable;
39*4882a593Smuzhiyun 	u32 sw_burst_req;
40*4882a593Smuzhiyun 	u32 sw_single_req;
41*4882a593Smuzhiyun 	u32 sw_last_burst_req;
42*4882a593Smuzhiyun 	u32 sw_last_single_req;
43*4882a593Smuzhiyun 	u32 config;
44*4882a593Smuzhiyun 	u32 sync;
45*4882a593Smuzhiyun 	u32 reserved[50];
46*4882a593Smuzhiyun 	struct dmac_chan_reg dma_chan[8];
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define DMA_NO_OF_CHANNELS	8
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* config register definitions */
52*4882a593Smuzhiyun #define DMAC_CTRL_ENABLE	(1 << 0) /* For enabling the DMA controller */
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun static u32 alloc_ch;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun static struct dma_reg *dma = (struct dma_reg *)DMA_BASE;
57*4882a593Smuzhiyun 
lpc32xx_dma_get_channel(void)58*4882a593Smuzhiyun int lpc32xx_dma_get_channel(void)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	int i;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	if (!alloc_ch) { /* First time caller */
63*4882a593Smuzhiyun 		/*
64*4882a593Smuzhiyun 		 * DMA clock are enable by "lpc32xx_dma_init()" and should
65*4882a593Smuzhiyun 		 * be call by board "board_early_init_f()" function.
66*4882a593Smuzhiyun 		 */
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 		/*
69*4882a593Smuzhiyun 		 * Make sure DMA controller and all channels are disabled.
70*4882a593Smuzhiyun 		 * Controller is in little-endian mode. Disable sync signals.
71*4882a593Smuzhiyun 		 */
72*4882a593Smuzhiyun 		writel(0, &dma->config);
73*4882a593Smuzhiyun 		writel(0, &dma->sync);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 		/* Clear interrupt and error statuses */
76*4882a593Smuzhiyun 		writel(0xFF, &dma->int_tc_clear);
77*4882a593Smuzhiyun 		writel(0xFF, &dma->raw_tc_stat);
78*4882a593Smuzhiyun 		writel(0xFF, &dma->int_err_clear);
79*4882a593Smuzhiyun 		writel(0xFF, &dma->raw_err_stat);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 		/* Enable DMA controller */
82*4882a593Smuzhiyun 		writel(DMAC_CTRL_ENABLE, &dma->config);
83*4882a593Smuzhiyun 	}
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	i = ffz(alloc_ch);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Check if all the available channels are busy */
88*4882a593Smuzhiyun 	if (unlikely(i == DMA_NO_OF_CHANNELS))
89*4882a593Smuzhiyun 		return -1;
90*4882a593Smuzhiyun 	alloc_ch |= BIT_MASK(i);
91*4882a593Smuzhiyun 	return i;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
lpc32xx_dma_start_xfer(unsigned int channel,const struct lpc32xx_dmac_ll * desc,u32 config)94*4882a593Smuzhiyun int lpc32xx_dma_start_xfer(unsigned int channel,
95*4882a593Smuzhiyun 			   const struct lpc32xx_dmac_ll *desc, u32 config)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	if (unlikely(((BIT_MASK(channel) & alloc_ch) == 0) ||
98*4882a593Smuzhiyun 		     (channel >= DMA_NO_OF_CHANNELS))) {
99*4882a593Smuzhiyun 		pr_err("Request for xfer on unallocated channel %d", channel);
100*4882a593Smuzhiyun 		return -1;
101*4882a593Smuzhiyun 	}
102*4882a593Smuzhiyun 	writel(BIT_MASK(channel), &dma->int_tc_clear);
103*4882a593Smuzhiyun 	writel(BIT_MASK(channel), &dma->int_err_clear);
104*4882a593Smuzhiyun 	writel(desc->dma_src, &dma->dma_chan[channel].src_addr);
105*4882a593Smuzhiyun 	writel(desc->dma_dest, &dma->dma_chan[channel].dest_addr);
106*4882a593Smuzhiyun 	writel(desc->next_lli, &dma->dma_chan[channel].lli);
107*4882a593Smuzhiyun 	writel(desc->next_ctrl, &dma->dma_chan[channel].control);
108*4882a593Smuzhiyun 	writel(config, &dma->dma_chan[channel].config_ch);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	return 0;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun 
lpc32xx_dma_wait_status(unsigned int channel)113*4882a593Smuzhiyun int lpc32xx_dma_wait_status(unsigned int channel)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	unsigned long start;
116*4882a593Smuzhiyun 	u32 reg;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	/* Check if given channel is valid */
119*4882a593Smuzhiyun 	if (unlikely(channel >= DMA_NO_OF_CHANNELS)) {
120*4882a593Smuzhiyun 		pr_err("Request for status on unallocated channel %d", channel);
121*4882a593Smuzhiyun 		return -1;
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	start = get_timer(0);
125*4882a593Smuzhiyun 	while (1) {
126*4882a593Smuzhiyun 		reg = readl(&dma->raw_tc_stat);
127*4882a593Smuzhiyun 		reg |= readl(dma->raw_err_stat);
128*4882a593Smuzhiyun 		if (reg & BIT_MASK(channel))
129*4882a593Smuzhiyun 			break;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 		if (get_timer(start) > CONFIG_SYS_HZ) {
132*4882a593Smuzhiyun 			pr_err("DMA status timeout channel %d\n", channel);
133*4882a593Smuzhiyun 			return -ETIMEDOUT;
134*4882a593Smuzhiyun 		}
135*4882a593Smuzhiyun 		udelay(1);
136*4882a593Smuzhiyun 	}
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	if (unlikely(readl(&dma->raw_err_stat) & BIT_MASK(channel))) {
139*4882a593Smuzhiyun 		setbits_le32(&dma->int_err_clear, BIT_MASK(channel));
140*4882a593Smuzhiyun 		setbits_le32(&dma->raw_err_stat, BIT_MASK(channel));
141*4882a593Smuzhiyun 		pr_err("DMA error on channel %d\n", channel);
142*4882a593Smuzhiyun 		return -1;
143*4882a593Smuzhiyun 	}
144*4882a593Smuzhiyun 	setbits_le32(&dma->int_tc_clear, BIT_MASK(channel));
145*4882a593Smuzhiyun 	setbits_le32(&dma->raw_tc_stat, BIT_MASK(channel));
146*4882a593Smuzhiyun 	return 0;
147*4882a593Smuzhiyun }
148