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