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