Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
f212ec4b BK |
2 | /* |
3 | * init_ohci1394_dma.c - Initializes physical DMA on all OHCI 1394 controllers | |
4 | * | |
5 | * Copyright (C) 2006-2007 Bernhard Kaindl <bk@suse.de> | |
6 | * | |
7 | * Derived from drivers/ieee1394/ohci1394.c and arch/x86/kernel/early-quirks.c | |
8 | * this file has functions to: | |
9 | * - scan the PCI very early on boot for all OHCI 1394-compliant controllers | |
10 | * - reset and initialize them and make them join the IEEE1394 bus and | |
11 | * - enable physical DMA on them to allow remote debugging | |
12 | * | |
13 | * All code and data is marked as __init and __initdata, respective as | |
14 | * during boot, all OHCI1394 controllers may be claimed by the firewire | |
15 | * stack and at this point, this code should not touch them anymore. | |
16 | * | |
17 | * To use physical DMA after the initialization of the firewire stack, | |
18 | * be sure that the stack enables it and (re-)attach after the bus reset | |
19 | * which may be caused by the firewire stack initialization. | |
f212ec4b BK |
20 | */ |
21 | ||
f212ec4b | 22 | #include <linux/delay.h> |
1ef5b816 SR |
23 | #include <linux/io.h> |
24 | #include <linux/kernel.h> | |
f212ec4b | 25 | #include <linux/pci.h> /* for PCI defines */ |
1ef5b816 SR |
26 | #include <linux/string.h> |
27 | ||
f212ec4b BK |
28 | #include <asm/pci-direct.h> /* for direct PCI config space access */ |
29 | #include <asm/fixmap.h> | |
30 | ||
1ef5b816 SR |
31 | #include <linux/init_ohci1394_dma.h> |
32 | #include "ohci.h" | |
f212ec4b BK |
33 | |
34 | int __initdata init_ohci1394_dma_early; | |
35 | ||
1ef5b816 SR |
36 | struct ohci { |
37 | void __iomem *registers; | |
38 | }; | |
39 | ||
40 | static inline void reg_write(const struct ohci *ohci, int offset, u32 data) | |
41 | { | |
42 | writel(data, ohci->registers + offset); | |
43 | } | |
44 | ||
45 | static inline u32 reg_read(const struct ohci *ohci, int offset) | |
46 | { | |
47 | return readl(ohci->registers + offset); | |
48 | } | |
49 | ||
50 | #define OHCI_LOOP_COUNT 100 /* Number of loops for reg read waits */ | |
51 | ||
f212ec4b | 52 | /* Reads a PHY register of an OHCI-1394 controller */ |
1ef5b816 | 53 | static inline u8 __init get_phy_reg(struct ohci *ohci, u8 addr) |
f212ec4b BK |
54 | { |
55 | int i; | |
1ef5b816 | 56 | u32 r; |
f212ec4b BK |
57 | |
58 | reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000); | |
59 | ||
60 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | |
61 | if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000) | |
62 | break; | |
63 | mdelay(1); | |
64 | } | |
65 | r = reg_read(ohci, OHCI1394_PhyControl); | |
66 | ||
67 | return (r & 0x00ff0000) >> 16; | |
68 | } | |
69 | ||
70 | /* Writes to a PHY register of an OHCI-1394 controller */ | |
1ef5b816 | 71 | static inline void __init set_phy_reg(struct ohci *ohci, u8 addr, u8 data) |
f212ec4b BK |
72 | { |
73 | int i; | |
74 | ||
75 | reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000); | |
76 | ||
77 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | |
1ef5b816 | 78 | if (!(reg_read(ohci, OHCI1394_PhyControl) & 0x00004000)) |
f212ec4b BK |
79 | break; |
80 | mdelay(1); | |
81 | } | |
82 | } | |
83 | ||
84 | /* Resets an OHCI-1394 controller (for sane state before initialization) */ | |
1ef5b816 SR |
85 | static inline void __init init_ohci1394_soft_reset(struct ohci *ohci) |
86 | { | |
f212ec4b BK |
87 | int i; |
88 | ||
89 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); | |
90 | ||
91 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | |
92 | if (!(reg_read(ohci, OHCI1394_HCControlSet) | |
93 | & OHCI1394_HCControl_softReset)) | |
94 | break; | |
95 | mdelay(1); | |
96 | } | |
97 | } | |
98 | ||
1ef5b816 SR |
99 | #define OHCI1394_MAX_AT_REQ_RETRIES 0xf |
100 | #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 | |
101 | #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 | |
102 | ||
f212ec4b | 103 | /* Basic OHCI-1394 register and port inititalization */ |
1ef5b816 | 104 | static inline void __init init_ohci1394_initialize(struct ohci *ohci) |
f212ec4b | 105 | { |
1ef5b816 | 106 | u32 bus_options; |
f212ec4b BK |
107 | int num_ports, i; |
108 | ||
109 | /* Put some defaults to these undefined bus options */ | |
110 | bus_options = reg_read(ohci, OHCI1394_BusOptions); | |
111 | bus_options |= 0x60000000; /* Enable CMC and ISC */ | |
112 | bus_options &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */ | |
113 | bus_options &= ~0x18000000; /* Disable PMC and BMC */ | |
114 | reg_write(ohci, OHCI1394_BusOptions, bus_options); | |
115 | ||
116 | /* Set the bus number */ | |
117 | reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0); | |
118 | ||
119 | /* Enable posted writes */ | |
120 | reg_write(ohci, OHCI1394_HCControlSet, | |
121 | OHCI1394_HCControl_postedWriteEnable); | |
122 | ||
123 | /* Clear link control register */ | |
124 | reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); | |
125 | ||
126 | /* enable phys */ | |
127 | reg_write(ohci, OHCI1394_LinkControlSet, | |
1ef5b816 | 128 | OHCI1394_LinkControl_rcvPhyPkt); |
f212ec4b BK |
129 | |
130 | /* Don't accept phy packets into AR request context */ | |
131 | reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400); | |
132 | ||
133 | /* Clear the Isochonouys interrupt masks */ | |
134 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff); | |
135 | reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff); | |
136 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff); | |
137 | reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff); | |
138 | ||
b3834be5 | 139 | /* Accept asynchronous transfer requests from all nodes for now */ |
1ef5b816 | 140 | reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); |
f212ec4b | 141 | |
b3834be5 | 142 | /* Specify asynchronous transfer retries */ |
f212ec4b BK |
143 | reg_write(ohci, OHCI1394_ATRetries, |
144 | OHCI1394_MAX_AT_REQ_RETRIES | | |
145 | (OHCI1394_MAX_AT_RESP_RETRIES<<4) | | |
146 | (OHCI1394_MAX_PHYS_RESP_RETRIES<<8)); | |
147 | ||
148 | /* We don't want hardware swapping */ | |
1ef5b816 SR |
149 | reg_write(ohci, OHCI1394_HCControlClear, |
150 | OHCI1394_HCControl_noByteSwapData); | |
f212ec4b BK |
151 | |
152 | /* Enable link */ | |
153 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable); | |
154 | ||
155 | /* If anything is connected to a port, make sure it is enabled */ | |
156 | num_ports = get_phy_reg(ohci, 2) & 0xf; | |
157 | for (i = 0; i < num_ports; i++) { | |
158 | unsigned int status; | |
159 | ||
160 | set_phy_reg(ohci, 7, i); | |
161 | status = get_phy_reg(ohci, 8); | |
162 | ||
163 | if (status & 0x20) | |
164 | set_phy_reg(ohci, 8, status & ~1); | |
165 | } | |
166 | } | |
167 | ||
168 | /** | |
169 | * init_ohci1394_wait_for_busresets - wait until bus resets are completed | |
170 | * | |
171 | * OHCI1394 initialization itself and any device going on- or offline | |
172 | * and any cable issue cause a IEEE1394 bus reset. The OHCI1394 spec | |
173 | * specifies that physical DMA is disabled on each bus reset and it | |
174 | * has to be enabled after each bus reset when needed. We resort | |
175 | * to polling here because on early boot, we have no interrupts. | |
176 | */ | |
1ef5b816 | 177 | static inline void __init init_ohci1394_wait_for_busresets(struct ohci *ohci) |
f212ec4b BK |
178 | { |
179 | int i, events; | |
180 | ||
1ef5b816 | 181 | for (i = 0; i < 9; i++) { |
f212ec4b BK |
182 | mdelay(200); |
183 | events = reg_read(ohci, OHCI1394_IntEventSet); | |
184 | if (events & OHCI1394_busReset) | |
185 | reg_write(ohci, OHCI1394_IntEventClear, | |
186 | OHCI1394_busReset); | |
187 | } | |
188 | } | |
189 | ||
190 | /** | |
191 | * init_ohci1394_enable_physical_dma - Enable physical DMA for remote debugging | |
192 | * This enables remote DMA access over IEEE1394 from every host for the low | |
193 | * 4GB of address space. DMA accesses above 4GB are not available currently. | |
194 | */ | |
1ef5b816 | 195 | static inline void __init init_ohci1394_enable_physical_dma(struct ohci *ohci) |
f212ec4b | 196 | { |
1ef5b816 SR |
197 | reg_write(ohci, OHCI1394_PhyReqFilterHiSet, 0xffffffff); |
198 | reg_write(ohci, OHCI1394_PhyReqFilterLoSet, 0xffffffff); | |
199 | reg_write(ohci, OHCI1394_PhyUpperBound, 0xffff0000); | |
f212ec4b BK |
200 | } |
201 | ||
202 | /** | |
203 | * init_ohci1394_reset_and_init_dma - init controller and enable DMA | |
204 | * This initializes the given controller and enables physical DMA engine in it. | |
205 | */ | |
1ef5b816 | 206 | static inline void __init init_ohci1394_reset_and_init_dma(struct ohci *ohci) |
f212ec4b BK |
207 | { |
208 | /* Start off with a soft reset, clears everything to a sane state. */ | |
209 | init_ohci1394_soft_reset(ohci); | |
210 | ||
211 | /* Accessing some registers without LPS enabled may cause lock up */ | |
212 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS); | |
213 | ||
214 | /* Disable and clear interrupts */ | |
215 | reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff); | |
216 | reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff); | |
217 | ||
218 | mdelay(50); /* Wait 50msec to make sure we have full link enabled */ | |
219 | ||
220 | init_ohci1394_initialize(ohci); | |
221 | /* | |
222 | * The initialization causes at least one IEEE1394 bus reset. Enabling | |
223 | * physical DMA only works *after* *all* bus resets have calmed down: | |
224 | */ | |
225 | init_ohci1394_wait_for_busresets(ohci); | |
226 | ||
227 | /* We had to wait and do this now if we want to debug early problems */ | |
228 | init_ohci1394_enable_physical_dma(ohci); | |
229 | } | |
230 | ||
231 | /** | |
232 | * init_ohci1394_controller - Map the registers of the controller and init DMA | |
233 | * This maps the registers of the specified controller and initializes it | |
234 | */ | |
235 | static inline void __init init_ohci1394_controller(int num, int slot, int func) | |
236 | { | |
237 | unsigned long ohci_base; | |
1ef5b816 | 238 | struct ohci ohci; |
f212ec4b BK |
239 | |
240 | printk(KERN_INFO "init_ohci1394_dma: initializing OHCI-1394" | |
241 | " at %02x:%02x.%x\n", num, slot, func); | |
242 | ||
243 | ohci_base = read_pci_config(num, slot, func, PCI_BASE_ADDRESS_0+(0<<2)) | |
244 | & PCI_BASE_ADDRESS_MEM_MASK; | |
245 | ||
246 | set_fixmap_nocache(FIX_OHCI1394_BASE, ohci_base); | |
247 | ||
1ef5b816 | 248 | ohci.registers = (void __iomem *)fix_to_virt(FIX_OHCI1394_BASE); |
f212ec4b BK |
249 | |
250 | init_ohci1394_reset_and_init_dma(&ohci); | |
251 | } | |
252 | ||
253 | /** | |
254 | * debug_init_ohci1394_dma - scan for OHCI1394 controllers and init DMA on them | |
255 | * Scans the whole PCI space for OHCI1394 controllers and inits DMA on them | |
256 | */ | |
257 | void __init init_ohci1394_dma_on_all_controllers(void) | |
258 | { | |
259 | int num, slot, func; | |
1ef5b816 | 260 | u32 class; |
f212ec4b BK |
261 | |
262 | if (!early_pci_allowed()) | |
263 | return; | |
264 | ||
265 | /* Poor man's PCI discovery, the only thing we can do at early boot */ | |
266 | for (num = 0; num < 32; num++) { | |
267 | for (slot = 0; slot < 32; slot++) { | |
268 | for (func = 0; func < 8; func++) { | |
1ef5b816 | 269 | class = read_pci_config(num, slot, func, |
f212ec4b | 270 | PCI_CLASS_REVISION); |
1ef5b816 | 271 | if (class == 0xffffffff) |
f212ec4b BK |
272 | continue; /* No device at this func */ |
273 | ||
274 | if (class>>8 != PCI_CLASS_SERIAL_FIREWIRE_OHCI) | |
275 | continue; /* Not an OHCI-1394 device */ | |
276 | ||
277 | init_ohci1394_controller(num, slot, func); | |
278 | break; /* Assume one controller per device */ | |
279 | } | |
280 | } | |
281 | } | |
282 | printk(KERN_INFO "init_ohci1394_dma: finished initializing OHCI DMA\n"); | |
283 | } | |
284 | ||
285 | /** | |
286 | * setup_init_ohci1394_early - enables early OHCI1394 DMA initialization | |
287 | */ | |
288 | static int __init setup_ohci1394_dma(char *opt) | |
289 | { | |
290 | if (!strcmp(opt, "early")) | |
291 | init_ohci1394_dma_early = 1; | |
292 | return 0; | |
293 | } | |
294 | ||
295 | /* passing ohci1394_dma=early on boot causes early OHCI1394 DMA initialization */ | |
296 | early_param("ohci1394_dma", setup_ohci1394_dma); |