1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <linux/interrupt.h>
36#include <linux/delay.h>
37#include <linux/pci.h>
38#include <linux/init_ohci1394_dma.h>
39#include <asm/pci-direct.h>
40#include <asm/fixmap.h>
41
42#include "ieee1394_types.h"
43#include "ohci1394.h"
44
45int __initdata init_ohci1394_dma_early;
46
47
48static inline u8 __init get_phy_reg(struct ti_ohci *ohci, u8 addr)
49{
50 int i;
51 quadlet_t r;
52
53 reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);
54
55 for (i = 0; i < OHCI_LOOP_COUNT; i++) {
56 if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)
57 break;
58 mdelay(1);
59 }
60 r = reg_read(ohci, OHCI1394_PhyControl);
61
62 return (r & 0x00ff0000) >> 16;
63}
64
65
66static inline void __init set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data)
67{
68 int i;
69
70 reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);
71
72 for (i = 0; i < OHCI_LOOP_COUNT; i++) {
73 u32 r = reg_read(ohci, OHCI1394_PhyControl);
74 if (!(r & 0x00004000))
75 break;
76 mdelay(1);
77 }
78}
79
80
81static inline void __init init_ohci1394_soft_reset(struct ti_ohci *ohci) {
82 int i;
83
84 reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
85
86 for (i = 0; i < OHCI_LOOP_COUNT; i++) {
87 if (!(reg_read(ohci, OHCI1394_HCControlSet)
88 & OHCI1394_HCControl_softReset))
89 break;
90 mdelay(1);
91 }
92}
93
94
95static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci)
96{
97 quadlet_t bus_options;
98 int num_ports, i;
99
100
101 bus_options = reg_read(ohci, OHCI1394_BusOptions);
102 bus_options |= 0x60000000;
103 bus_options &= ~0x00ff0000;
104 bus_options &= ~0x18000000;
105 reg_write(ohci, OHCI1394_BusOptions, bus_options);
106
107
108 reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);
109
110
111 reg_write(ohci, OHCI1394_HCControlSet,
112 OHCI1394_HCControl_postedWriteEnable);
113
114
115 reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
116
117
118 reg_write(ohci, OHCI1394_LinkControlSet,
119 OHCI1394_LinkControl_RcvPhyPkt);
120
121
122 reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
123
124
125 reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);
126 reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);
127 reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
128 reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
129
130
131 reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0x80000000);
132
133
134 reg_write(ohci, OHCI1394_ATRetries,
135 OHCI1394_MAX_AT_REQ_RETRIES |
136 (OHCI1394_MAX_AT_RESP_RETRIES<<4) |
137 (OHCI1394_MAX_PHYS_RESP_RETRIES<<8));
138
139
140 reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwap);
141
142
143 reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
144
145
146 num_ports = get_phy_reg(ohci, 2) & 0xf;
147 for (i = 0; i < num_ports; i++) {
148 unsigned int status;
149
150 set_phy_reg(ohci, 7, i);
151 status = get_phy_reg(ohci, 8);
152
153 if (status & 0x20)
154 set_phy_reg(ohci, 8, status & ~1);
155 }
156}
157
158
159
160
161
162
163
164
165
166
167static inline void __init init_ohci1394_wait_for_busresets(struct ti_ohci *ohci)
168{
169 int i, events;
170
171 for (i=0; i < 9; i++) {
172 mdelay(200);
173 events = reg_read(ohci, OHCI1394_IntEventSet);
174 if (events & OHCI1394_busReset)
175 reg_write(ohci, OHCI1394_IntEventClear,
176 OHCI1394_busReset);
177 }
178}
179
180
181
182
183
184
185static inline void __init init_ohci1394_enable_physical_dma(struct ti_ohci *hci)
186{
187 reg_write(hci, OHCI1394_PhyReqFilterHiSet, 0xffffffff);
188 reg_write(hci, OHCI1394_PhyReqFilterLoSet, 0xffffffff);
189 reg_write(hci, OHCI1394_PhyUpperBound, 0xffff0000);
190}
191
192
193
194
195
196static inline void __init init_ohci1394_reset_and_init_dma(struct ti_ohci *ohci)
197{
198
199 init_ohci1394_soft_reset(ohci);
200
201
202 reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS);
203
204
205 reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
206 reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
207
208 mdelay(50);
209
210 init_ohci1394_initialize(ohci);
211
212
213
214
215 init_ohci1394_wait_for_busresets(ohci);
216
217
218 init_ohci1394_enable_physical_dma(ohci);
219}
220
221
222
223
224
225static inline void __init init_ohci1394_controller(int num, int slot, int func)
226{
227 unsigned long ohci_base;
228 struct ti_ohci ohci;
229
230 printk(KERN_INFO "init_ohci1394_dma: initializing OHCI-1394"
231 " at %02x:%02x.%x\n", num, slot, func);
232
233 ohci_base = read_pci_config(num, slot, func, PCI_BASE_ADDRESS_0+(0<<2))
234 & PCI_BASE_ADDRESS_MEM_MASK;
235
236 set_fixmap_nocache(FIX_OHCI1394_BASE, ohci_base);
237
238 ohci.registers = (void *)fix_to_virt(FIX_OHCI1394_BASE);
239
240 init_ohci1394_reset_and_init_dma(&ohci);
241}
242
243
244
245
246
247void __init init_ohci1394_dma_on_all_controllers(void)
248{
249 int num, slot, func;
250
251 if (!early_pci_allowed())
252 return;
253
254
255 for (num = 0; num < 32; num++) {
256 for (slot = 0; slot < 32; slot++) {
257 for (func = 0; func < 8; func++) {
258 u32 class = read_pci_config(num,slot,func,
259 PCI_CLASS_REVISION);
260 if ((class == 0xffffffff))
261 continue;
262
263 if (class>>8 != PCI_CLASS_SERIAL_FIREWIRE_OHCI)
264 continue;
265
266 init_ohci1394_controller(num, slot, func);
267 break;
268 }
269 }
270 }
271 printk(KERN_INFO "init_ohci1394_dma: finished initializing OHCI DMA\n");
272}
273
274
275
276
277static int __init setup_ohci1394_dma(char *opt)
278{
279 if (!strcmp(opt, "early"))
280 init_ohci1394_dma_early = 1;
281 return 0;
282}
283
284
285early_param("ohci1394_dma", setup_ohci1394_dma);
286