1 /*
2  * arch/ppc/kernel/ppc4xx_stbdma.c
3  *
4  * BRIEF MODULE DESCRIPTION
5  *	IBM PPC4xx STBxxxx DMA Controller Functions
6  *
7  * Copyright 2002 MontaVista Software Inc.
8  * Author: MontaVista Software, Inc.
9  *         Armin Kuster <akuster@mvista.com>
10  *
11  *   Based on ppc4xx_dma.c by
12  *         ppopov@mvista.com or source@mvista.
13  *
14  *  This program is free software; you can redistribute  it and/or modify it
15  *  under  the terms of  the GNU General  Public License as published by the
16  *  Free Software Foundation;  either version 2 of the  License, or (at your
17  *  option) any later version.
18  *
19  *  You should have received a copy of the  GNU General Public License along
20  *  with this program; if not, write  to the Free Software Foundation, Inc.,
21  *  675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23 
24 #include <linux/config.h>
25 #include <linux/kernel.h>
26 #include <asm/system.h>
27 #include <asm/io.h>
28 #include <linux/mm.h>
29 #include <linux/miscdevice.h>
30 #include <linux/init.h>
31 #include <linux/module.h>
32 
33 #include <asm/ppc4xx_dma.h>
34 
35 int
ppc4xx_clr_dma_status(unsigned int dmanr)36 ppc4xx_clr_dma_status(unsigned int dmanr)
37 {
38 	unsigned int control;
39 	ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
40 
41 	p_dma_ch->int_enable = 1;
42 
43 	switch (dmanr) {
44 	case 0:
45 		control = DMA_CS0 | DMA_CH0_ERR | DMA_CT0;
46 		break;
47 	case 1:
48 		control = DMA_CS1 | DMA_CH1_ERR | DMA_CT1;
49 		break;
50 	case 2:
51 		control = DMA_CS2 | DMA_CH2_ERR | DMA_CT2;
52 		break;
53 	case 3:
54 		control = DMA_CS3 | DMA_CH3_ERR | DMA_CT3;
55 		break;
56 	default:
57 #ifdef DEBUG_4xxDMA
58 		printk("ppc4xx_clr_dma_status: bad channel: %d\n", dmanr);
59 #endif
60 		return DMA_STATUS_BAD_CHANNEL;
61 	}
62 	mtdcr(DCRN_DMASR, control);
63 	return DMA_STATUS_GOOD;
64 }
65 
66 /*
67  * Maps a given port to a one of the dma
68  * channels
69  */
70 int
ppc4xx_map_dma_port(unsigned int dmanr,unsigned int ocp_dma,short dma_chan)71 ppc4xx_map_dma_port(unsigned int dmanr, unsigned int ocp_dma,short dma_chan)
72 {
73 	unsigned int map;
74 	int connect_port_to_chan, select;
75 
76 	ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
77 
78 	connect_port_to_chan = ((ocp_dma & 0x7)*4);
79 
80 	select = ocp_dma >> 3;
81 	switch (select) {
82 	case 0:
83 		map = mfdcr(DCRN_DMAS1);
84 		map |= (connect_port_to_chan << dma_chan);	/* */
85 		mtdcr(DCRN_DMAS1, map);
86 		break;
87 	case 1:
88 		map = mfdcr(DCRN_DMAS2);
89 		map |= (connect_port_to_chan << dma_chan);
90 		mtdcr(DCRN_DMAS2, map);
91 		break;
92 	default:
93 #ifdef DEBUG_4xxDMA
94 		printk("map_dma_port: bad channel: %d\n", dmanr);
95 #endif
96 		return DMA_STATUS_BAD_CHANNEL;
97 	}
98 	return DMA_STATUS_GOOD;
99 }
100 
101 int
ppc4xx_disable_dma_port(unsigned int dmanr,unsigned int ocp_dma,short dma_chan)102 ppc4xx_disable_dma_port(unsigned int dmanr, unsigned int ocp_dma,short dma_chan)
103 {
104 	unsigned int map;
105 	int connect_port_to_chan, select;
106 
107 	ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
108 
109 	connect_port_to_chan = ((ocp_dma & 0x7)*4);
110 
111 	select = ocp_dma >> 3;
112 	switch (select) {
113 	case 0:
114 		map = mfdcr(DCRN_DMAS1);
115 		map &= ~(connect_port_to_chan << dma_chan);	/* */
116 		mtdcr(DCRN_DMAS1, map);
117 		break;
118 	case 1:
119 		map = mfdcr(DCRN_DMAS2);
120 		map &= ~(connect_port_to_chan << dma_chan);
121 		mtdcr(DCRN_DMAS2, map);
122 		break;
123 	default:
124 #ifdef DEBUG_4xxDMA
125 		printk("disable_dma_port: bad channel: %d\n", dmanr);
126 #endif
127 		return DMA_STATUS_BAD_CHANNEL;
128 	}
129 	return DMA_STATUS_GOOD;
130 }
131 
132 EXPORT_SYMBOL(ppc4xx_disable_dma_port);
133 EXPORT_SYMBOL(ppc4xx_map_dma_port);
134 EXPORT_SYMBOL(ppc4xx_clr_dma_status);
135