v2.4.2.7 -> v2.4.2.8
[linux-flexiantxendom0-3.2.10.git] / include / asm-sparc64 / parport.h
1 /* $Id: parport.h,v 1.10 2001/03/24 00:18:57 davem Exp $
2  * parport.h: sparc64 specific parport initialization and dma.
3  *
4  * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
5  */
6
7 #ifndef _ASM_SPARC64_PARPORT_H
8 #define _ASM_SPARC64_PARPORT_H 1
9
10 #include <asm/ebus.h>
11 #include <asm/ns87303.h>
12
13 #define PARPORT_PC_MAX_PORTS    PARPORT_MAX
14
15 static struct linux_ebus_dma *sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
16
17 static __inline__ void
18 reset_dma(unsigned int dmanr)
19 {
20         unsigned int dcsr;
21
22         writel(EBUS_DCSR_RESET, &sparc_ebus_dmas[dmanr]->dcsr);
23         udelay(1);
24         dcsr = EBUS_DCSR_BURST_SZ_16 | EBUS_DCSR_TCI_DIS |
25                EBUS_DCSR_EN_CNT | EBUS_DCSR_INT_EN;
26         writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
27 }
28
29 static __inline__ void
30 enable_dma(unsigned int dmanr)
31 {
32         unsigned int dcsr;
33
34         dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
35         dcsr |= EBUS_DCSR_EN_DMA;
36         writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
37 }
38
39 static __inline__ void
40 disable_dma(unsigned int dmanr)
41 {
42         unsigned int dcsr;
43
44         dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
45         if (dcsr & EBUS_DCSR_EN_DMA) {
46                 while (dcsr & EBUS_DCSR_DRAIN) {
47                         udelay(1);
48                         dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
49                 }
50                 dcsr &= ~(EBUS_DCSR_EN_DMA);
51                 writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
52
53                 dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
54                 if (dcsr & EBUS_DCSR_ERR_PEND)
55                         reset_dma(dmanr);
56         }
57 }
58
59 static __inline__ void
60 clear_dma_ff(unsigned int dmanr)
61 {
62         /* nothing */
63 }
64
65 static __inline__ void
66 set_dma_mode(unsigned int dmanr, char mode)
67 {
68         unsigned int dcsr;
69
70         dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
71         dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;
72         if (mode == DMA_MODE_WRITE)
73                 dcsr &= ~(EBUS_DCSR_WRITE);
74         else
75                 dcsr |= EBUS_DCSR_WRITE;
76         writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
77 }
78
79 static __inline__ void
80 set_dma_addr(unsigned int dmanr, unsigned int addr)
81 {
82         writel(addr, &sparc_ebus_dmas[dmanr]->dacr);
83 }
84
85 static __inline__ void
86 set_dma_count(unsigned int dmanr, unsigned int count)
87 {
88         writel(count, &sparc_ebus_dmas[dmanr]->dbcr);
89 }
90
91 static __inline__ int
92 get_dma_residue(unsigned int dmanr)
93 {
94         int res;
95
96         res = readl(&sparc_ebus_dmas[dmanr]->dbcr);
97         if (res != 0)
98                 reset_dma(dmanr);
99         return res;
100 }
101
102 static int ebus_ecpp_p(struct linux_ebus_device *edev)
103 {
104         if (!strcmp(edev->prom_name, "ecpp"))
105                 return 1;
106         if (!strcmp(edev->prom_name, "parallel")) {
107                 char compat[19];
108                 prom_getstring(edev->prom_node,
109                                "compatible",
110                                compat, sizeof(compat));
111                 compat[18] = '\0';
112                 if (!strcmp(compat, "ecpp"))
113                         return 1;
114                 if (!strcmp(compat, "ns87317-ecpp") &&
115                     !strcmp(compat + 13, "ecpp"))
116                         return 1;
117         }
118         return 0;
119 }
120
121 static int parport_pc_find_nonpci_ports (int autoirq, int autodma)
122 {
123         struct linux_ebus *ebus;
124         struct linux_ebus_device *edev;
125         int count = 0;
126
127         if (!pci_present())
128                 return 0;
129
130         for_each_ebus(ebus) {
131                 for_each_ebusdev(edev, ebus) {
132                         if (ebus_ecpp_p(edev)) {
133                                 unsigned long base = edev->resource[0].start;
134                                 unsigned long config = edev->resource[1].start;
135
136                                 sparc_ebus_dmas[count] =
137                                                 (struct linux_ebus_dma *)
138                                                         edev->resource[2].start;
139                                 reset_dma(count);
140
141                                 /* Configure IRQ to Push Pull, Level Low */
142                                 /* Enable ECP, set bit 2 of the CTR first */
143                                 outb(0x04, base + 0x02);
144                                 ns87303_modify(config, PCR,
145                                                PCR_EPP_ENABLE |
146                                                PCR_IRQ_ODRAIN,
147                                                PCR_ECP_ENABLE |
148                                                PCR_ECP_CLK_ENA |
149                                                PCR_IRQ_POLAR);
150
151                                 /* CTR bit 5 controls direction of port */
152                                 ns87303_modify(config, PTR,
153                                                0, PTR_LPT_REG_DIR);
154
155                                 if (parport_pc_probe_port(base, base + 0x400,
156                                                           edev->irqs[0],
157                                                           count, ebus->self))
158                                         count++;
159                         }
160                 }
161         }
162
163         return count;
164 }
165
166 #endif /* !(_ASM_SPARC64_PARPORT_H */