synclink_gt: use pci_zalloc_consistent
[deliverable/linux.git] / drivers / vme / bridges / vme_tsi148.c
CommitLineData
d22b8ed9
MW
1/*
2 * Support for the Tundra TSI148 VME-PCI Bridge Chip
3 *
66bd8db5
MW
4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
d22b8ed9
MW
6 *
7 * Based on work by Tom Armistead and Ajit Prem
8 * Copyright 2004 Motorola Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
d22b8ed9
MW
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/mm.h>
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/proc_fs.h>
22#include <linux/pci.h>
23#include <linux/poll.h>
24#include <linux/dma-mapping.h>
25#include <linux/interrupt.h>
26#include <linux/spinlock.h>
6af783c8 27#include <linux/sched.h>
5a0e3ad6 28#include <linux/slab.h>
7946328f
MW
29#include <linux/time.h>
30#include <linux/io.h>
31#include <linux/uaccess.h>
ac1a4f2c 32#include <linux/byteorder/generic.h>
db3b9e99 33#include <linux/vme.h>
d22b8ed9 34
d22b8ed9
MW
35#include "../vme_bridge.h"
36#include "vme_tsi148.h"
37
d22b8ed9
MW
38static int tsi148_probe(struct pci_dev *, const struct pci_device_id *);
39static void tsi148_remove(struct pci_dev *);
d22b8ed9
MW
40
41
29848ac9 42/* Module parameter */
90ab5ee9 43static bool err_chk;
638f199d 44static int geoid;
d22b8ed9 45
584721ca 46static const char driver_name[] = "vme_tsi148";
d22b8ed9 47
c3a09c18 48static const struct pci_device_id tsi148_ids[] = {
d22b8ed9
MW
49 { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
50 { },
51};
52
53static struct pci_driver tsi148_driver = {
54 .name = driver_name,
55 .id_table = tsi148_ids,
56 .probe = tsi148_probe,
57 .remove = tsi148_remove,
58};
59
60static void reg_join(unsigned int high, unsigned int low,
61 unsigned long long *variable)
62{
63 *variable = (unsigned long long)high << 32;
64 *variable |= (unsigned long long)low;
65}
66
67static void reg_split(unsigned long long variable, unsigned int *high,
68 unsigned int *low)
69{
70 *low = (unsigned int)variable & 0xFFFFFFFF;
71 *high = (unsigned int)(variable >> 32);
72}
73
74/*
75 * Wakes up DMA queue.
76 */
29848ac9
MW
77static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
78 int channel_mask)
d22b8ed9
MW
79{
80 u32 serviced = 0;
81
82 if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
886953e9 83 wake_up(&bridge->dma_queue[0]);
d22b8ed9
MW
84 serviced |= TSI148_LCSR_INTC_DMA0C;
85 }
86 if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
886953e9 87 wake_up(&bridge->dma_queue[1]);
d22b8ed9
MW
88 serviced |= TSI148_LCSR_INTC_DMA1C;
89 }
90
91 return serviced;
92}
93
94/*
95 * Wake up location monitor queue
96 */
29848ac9 97static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
d22b8ed9
MW
98{
99 int i;
100 u32 serviced = 0;
101
102 for (i = 0; i < 4; i++) {
7946328f 103 if (stat & TSI148_LCSR_INTS_LMS[i]) {
d22b8ed9 104 /* We only enable interrupts if the callback is set */
29848ac9 105 bridge->lm_callback[i](i);
d22b8ed9
MW
106 serviced |= TSI148_LCSR_INTC_LMC[i];
107 }
108 }
109
110 return serviced;
111}
112
113/*
114 * Wake up mail box queue.
115 *
116 * XXX This functionality is not exposed up though API.
117 */
48d9356e 118static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat)
d22b8ed9
MW
119{
120 int i;
121 u32 val;
122 u32 serviced = 0;
48d9356e
MW
123 struct tsi148_driver *bridge;
124
125 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
126
127 for (i = 0; i < 4; i++) {
7946328f 128 if (stat & TSI148_LCSR_INTS_MBS[i]) {
29848ac9 129 val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]);
48d9356e
MW
130 dev_err(tsi148_bridge->parent, "VME Mailbox %d received"
131 ": 0x%x\n", i, val);
d22b8ed9
MW
132 serviced |= TSI148_LCSR_INTC_MBC[i];
133 }
134 }
135
136 return serviced;
137}
138
139/*
140 * Display error & status message when PERR (PCI) exception interrupt occurs.
141 */
48d9356e 142static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge)
d22b8ed9 143{
48d9356e
MW
144 struct tsi148_driver *bridge;
145
146 bridge = tsi148_bridge->driver_priv;
147
148 dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, "
149 "attributes: %08x\n",
29848ac9
MW
150 ioread32be(bridge->base + TSI148_LCSR_EDPAU),
151 ioread32be(bridge->base + TSI148_LCSR_EDPAL),
48d9356e
MW
152 ioread32be(bridge->base + TSI148_LCSR_EDPAT));
153
154 dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split "
155 "completion reg: %08x\n",
29848ac9 156 ioread32be(bridge->base + TSI148_LCSR_EDPXA),
48d9356e 157 ioread32be(bridge->base + TSI148_LCSR_EDPXS));
d22b8ed9 158
29848ac9 159 iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT);
d22b8ed9
MW
160
161 return TSI148_LCSR_INTC_PERRC;
162}
163
164/*
165 * Save address and status when VME error interrupt occurs.
166 */
29848ac9 167static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
d22b8ed9
MW
168{
169 unsigned int error_addr_high, error_addr_low;
170 unsigned long long error_addr;
171 u32 error_attrib;
e31c51e4 172 struct vme_bus_error *error = NULL;
29848ac9
MW
173 struct tsi148_driver *bridge;
174
175 bridge = tsi148_bridge->driver_priv;
d22b8ed9 176
29848ac9
MW
177 error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU);
178 error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL);
179 error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT);
d22b8ed9
MW
180
181 reg_join(error_addr_high, error_addr_low, &error_addr);
182
183 /* Check for exception register overflow (we have lost error data) */
7946328f 184 if (error_attrib & TSI148_LCSR_VEAT_VEOF) {
48d9356e
MW
185 dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow "
186 "Occurred\n");
d22b8ed9
MW
187 }
188
e31c51e4
MW
189 if (err_chk) {
190 error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC);
191 if (error) {
192 error->address = error_addr;
193 error->attributes = error_attrib;
194 list_add_tail(&error->list, &tsi148_bridge->vme_errors);
195 } else {
196 dev_err(tsi148_bridge->parent,
197 "Unable to alloc memory for VMEbus Error reporting\n");
198 }
199 }
200
201 if (!error) {
202 dev_err(tsi148_bridge->parent,
203 "VME Bus Error at address: 0x%llx, attributes: %08x\n",
204 error_addr, error_attrib);
d22b8ed9
MW
205 }
206
207 /* Clear Status */
29848ac9 208 iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT);
d22b8ed9
MW
209
210 return TSI148_LCSR_INTC_VERRC;
211}
212
213/*
214 * Wake up IACK queue.
215 */
29848ac9 216static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
d22b8ed9 217{
886953e9 218 wake_up(&bridge->iack_queue);
d22b8ed9
MW
219
220 return TSI148_LCSR_INTC_IACKC;
221}
222
223/*
224 * Calling VME bus interrupt callback if provided.
225 */
29848ac9
MW
226static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
227 u32 stat)
d22b8ed9
MW
228{
229 int vec, i, serviced = 0;
29848ac9
MW
230 struct tsi148_driver *bridge;
231
232 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
233
234 for (i = 7; i > 0; i--) {
235 if (stat & (1 << i)) {
236 /*
7946328f
MW
237 * Note: Even though the registers are defined as
238 * 32-bits in the spec, we only want to issue 8-bit
239 * IACK cycles on the bus, read from offset 3.
d22b8ed9 240 */
29848ac9 241 vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3);
d22b8ed9 242
c813f592 243 vme_irq_handler(tsi148_bridge, i, vec);
d22b8ed9
MW
244
245 serviced |= (1 << i);
246 }
247 }
248
249 return serviced;
250}
251
252/*
253 * Top level interrupt handler. Clears appropriate interrupt status bits and
254 * then calls appropriate sub handler(s).
255 */
29848ac9 256static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
d22b8ed9
MW
257{
258 u32 stat, enable, serviced = 0;
29848ac9
MW
259 struct vme_bridge *tsi148_bridge;
260 struct tsi148_driver *bridge;
261
262 tsi148_bridge = ptr;
263
264 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
265
266 /* Determine which interrupts are unmasked and set */
29848ac9
MW
267 enable = ioread32be(bridge->base + TSI148_LCSR_INTEO);
268 stat = ioread32be(bridge->base + TSI148_LCSR_INTS);
d22b8ed9
MW
269
270 /* Only look at unmasked interrupts */
271 stat &= enable;
272
7946328f 273 if (unlikely(!stat))
d22b8ed9 274 return IRQ_NONE;
d22b8ed9
MW
275
276 /* Call subhandlers as appropriate */
277 /* DMA irqs */
278 if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
29848ac9 279 serviced |= tsi148_DMA_irqhandler(bridge, stat);
d22b8ed9
MW
280
281 /* Location monitor irqs */
282 if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
283 TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
29848ac9 284 serviced |= tsi148_LM_irqhandler(bridge, stat);
d22b8ed9
MW
285
286 /* Mail box irqs */
287 if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
288 TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
48d9356e 289 serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat);
d22b8ed9
MW
290
291 /* PCI bus error */
292 if (stat & TSI148_LCSR_INTS_PERRS)
48d9356e 293 serviced |= tsi148_PERR_irqhandler(tsi148_bridge);
d22b8ed9
MW
294
295 /* VME bus error */
296 if (stat & TSI148_LCSR_INTS_VERRS)
29848ac9 297 serviced |= tsi148_VERR_irqhandler(tsi148_bridge);
d22b8ed9
MW
298
299 /* IACK irq */
300 if (stat & TSI148_LCSR_INTS_IACKS)
29848ac9 301 serviced |= tsi148_IACK_irqhandler(bridge);
d22b8ed9
MW
302
303 /* VME bus irqs */
304 if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
305 TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
306 TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
307 TSI148_LCSR_INTS_IRQ1S))
29848ac9 308 serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat);
d22b8ed9
MW
309
310 /* Clear serviced interrupts */
29848ac9 311 iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC);
d22b8ed9
MW
312
313 return IRQ_HANDLED;
314}
315
29848ac9 316static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
d22b8ed9
MW
317{
318 int result;
319 unsigned int tmp;
320 struct pci_dev *pdev;
29848ac9
MW
321 struct tsi148_driver *bridge;
322
177581fa 323 pdev = to_pci_dev(tsi148_bridge->parent);
d22b8ed9 324
29848ac9 325 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
326
327 /* Initialise list for VME bus errors */
886953e9 328 INIT_LIST_HEAD(&tsi148_bridge->vme_errors);
d22b8ed9 329
886953e9 330 mutex_init(&tsi148_bridge->irq_mtx);
c813f592 331
d22b8ed9
MW
332 result = request_irq(pdev->irq,
333 tsi148_irqhandler,
334 IRQF_SHARED,
29848ac9 335 driver_name, tsi148_bridge);
d22b8ed9 336 if (result) {
48d9356e
MW
337 dev_err(tsi148_bridge->parent, "Can't get assigned pci irq "
338 "vector %02X\n", pdev->irq);
d22b8ed9
MW
339 return result;
340 }
341
342 /* Enable and unmask interrupts */
343 tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO |
344 TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO |
345 TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO |
346 TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
347 TSI148_LCSR_INTEO_IACKEO;
348
29848ac9 349 /* This leaves the following interrupts masked.
d22b8ed9
MW
350 * TSI148_LCSR_INTEO_VIEEO
351 * TSI148_LCSR_INTEO_SYSFLEO
352 * TSI148_LCSR_INTEO_ACFLEO
353 */
354
355 /* Don't enable Location Monitor interrupts here - they will be
356 * enabled when the location monitors are properly configured and
357 * a callback has been attached.
358 * TSI148_LCSR_INTEO_LM0EO
359 * TSI148_LCSR_INTEO_LM1EO
360 * TSI148_LCSR_INTEO_LM2EO
361 * TSI148_LCSR_INTEO_LM3EO
362 */
363
364 /* Don't enable VME interrupts until we add a handler, else the board
365 * will respond to it and we don't want that unless it knows how to
366 * properly deal with it.
367 * TSI148_LCSR_INTEO_IRQ7EO
368 * TSI148_LCSR_INTEO_IRQ6EO
369 * TSI148_LCSR_INTEO_IRQ5EO
370 * TSI148_LCSR_INTEO_IRQ4EO
371 * TSI148_LCSR_INTEO_IRQ3EO
372 * TSI148_LCSR_INTEO_IRQ2EO
373 * TSI148_LCSR_INTEO_IRQ1EO
374 */
375
376 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
377 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
378
379 return 0;
380}
381
a82ad05e
EC
382static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge,
383 struct pci_dev *pdev)
d22b8ed9 384{
a82ad05e
EC
385 struct tsi148_driver *bridge = tsi148_bridge->driver_priv;
386
d22b8ed9 387 /* Turn off interrupts */
29848ac9
MW
388 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO);
389 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN);
d22b8ed9
MW
390
391 /* Clear all interrupts */
29848ac9 392 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC);
d22b8ed9
MW
393
394 /* Detach interrupt handler */
a82ad05e 395 free_irq(pdev->irq, tsi148_bridge);
d22b8ed9
MW
396}
397
398/*
399 * Check to see if an IACk has been received, return true (1) or false (0).
400 */
5ade6c4d 401static int tsi148_iack_received(struct tsi148_driver *bridge)
d22b8ed9
MW
402{
403 u32 tmp;
404
29848ac9 405 tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
406
407 if (tmp & TSI148_LCSR_VICR_IRQS)
408 return 0;
409 else
410 return 1;
411}
412
413/*
c813f592 414 * Configure VME interrupt
d22b8ed9 415 */
5ade6c4d 416static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
29848ac9 417 int state, int sync)
d22b8ed9 418{
75155020 419 struct pci_dev *pdev;
c813f592 420 u32 tmp;
29848ac9
MW
421 struct tsi148_driver *bridge;
422
423 bridge = tsi148_bridge->driver_priv;
d22b8ed9 424
c813f592
MW
425 /* We need to do the ordering differently for enabling and disabling */
426 if (state == 0) {
29848ac9 427 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 428 tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
29848ac9 429 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
df455175 430
29848ac9 431 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
df455175 432 tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
29848ac9 433 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
75155020 434
c813f592 435 if (sync != 0) {
177581fa 436 pdev = to_pci_dev(tsi148_bridge->parent);
c813f592
MW
437 synchronize_irq(pdev->irq);
438 }
439 } else {
29848ac9 440 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
c813f592 441 tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
29848ac9 442 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
df455175 443
29848ac9 444 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
c813f592 445 tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
29848ac9 446 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
c813f592 447 }
d22b8ed9
MW
448}
449
450/*
451 * Generate a VME bus interrupt at the requested level & vector. Wait for
452 * interrupt to be acked.
d22b8ed9 453 */
5ade6c4d
EC
454static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level,
455 int statid)
d22b8ed9
MW
456{
457 u32 tmp;
29848ac9
MW
458 struct tsi148_driver *bridge;
459
460 bridge = tsi148_bridge->driver_priv;
d22b8ed9 461
886953e9 462 mutex_lock(&bridge->vme_int);
d22b8ed9
MW
463
464 /* Read VICR register */
29848ac9 465 tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
466
467 /* Set Status/ID */
468 tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
469 (statid & TSI148_LCSR_VICR_STID_M);
29848ac9 470 iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
471
472 /* Assert VMEbus IRQ */
473 tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
29848ac9 474 iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
475
476 /* XXX Consider implementing a timeout? */
29848ac9
MW
477 wait_event_interruptible(bridge->iack_queue,
478 tsi148_iack_received(bridge));
d22b8ed9 479
886953e9 480 mutex_unlock(&bridge->vme_int);
d22b8ed9
MW
481
482 return 0;
483}
484
485/*
486 * Find the first error in this address range
487 */
29848ac9 488static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge,
6af04b06 489 u32 aspace, unsigned long long address, size_t count)
d22b8ed9
MW
490{
491 struct list_head *err_pos;
492 struct vme_bus_error *vme_err, *valid = NULL;
493 unsigned long long bound;
494
495 bound = address + count;
496
497 /*
498 * XXX We are currently not looking at the address space when parsing
499 * for errors. This is because parsing the Address Modifier Codes
500 * is going to be quite resource intensive to do properly. We
501 * should be OK just looking at the addresses and this is certainly
502 * much better than what we had before.
503 */
504 err_pos = NULL;
505 /* Iterate through errors */
886953e9 506 list_for_each(err_pos, &tsi148_bridge->vme_errors) {
d22b8ed9 507 vme_err = list_entry(err_pos, struct vme_bus_error, list);
7946328f
MW
508 if ((vme_err->address >= address) &&
509 (vme_err->address < bound)) {
510
d22b8ed9
MW
511 valid = vme_err;
512 break;
513 }
514 }
515
516 return valid;
517}
518
519/*
520 * Clear errors in the provided address range.
521 */
29848ac9 522static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge,
6af04b06 523 u32 aspace, unsigned long long address, size_t count)
d22b8ed9
MW
524{
525 struct list_head *err_pos, *temp;
526 struct vme_bus_error *vme_err;
527 unsigned long long bound;
528
529 bound = address + count;
530
531 /*
532 * XXX We are currently not looking at the address space when parsing
533 * for errors. This is because parsing the Address Modifier Codes
534 * is going to be quite resource intensive to do properly. We
535 * should be OK just looking at the addresses and this is certainly
536 * much better than what we had before.
537 */
538 err_pos = NULL;
539 /* Iterate through errors */
886953e9 540 list_for_each_safe(err_pos, temp, &tsi148_bridge->vme_errors) {
d22b8ed9
MW
541 vme_err = list_entry(err_pos, struct vme_bus_error, list);
542
7946328f
MW
543 if ((vme_err->address >= address) &&
544 (vme_err->address < bound)) {
545
d22b8ed9
MW
546 list_del(err_pos);
547 kfree(vme_err);
548 }
549 }
550}
551
552/*
553 * Initialize a slave window with the requested attributes.
554 */
5ade6c4d 555static int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
d22b8ed9 556 unsigned long long vme_base, unsigned long long size,
6af04b06 557 dma_addr_t pci_base, u32 aspace, u32 cycle)
d22b8ed9
MW
558{
559 unsigned int i, addr = 0, granularity = 0;
560 unsigned int temp_ctl = 0;
561 unsigned int vme_base_low, vme_base_high;
562 unsigned int vme_bound_low, vme_bound_high;
563 unsigned int pci_offset_low, pci_offset_high;
564 unsigned long long vme_bound, pci_offset;
48d9356e 565 struct vme_bridge *tsi148_bridge;
29848ac9
MW
566 struct tsi148_driver *bridge;
567
48d9356e
MW
568 tsi148_bridge = image->parent;
569 bridge = tsi148_bridge->driver_priv;
d22b8ed9 570
d22b8ed9
MW
571 i = image->number;
572
573 switch (aspace) {
574 case VME_A16:
575 granularity = 0x10;
576 addr |= TSI148_LCSR_ITAT_AS_A16;
577 break;
578 case VME_A24:
579 granularity = 0x1000;
580 addr |= TSI148_LCSR_ITAT_AS_A24;
581 break;
582 case VME_A32:
583 granularity = 0x10000;
584 addr |= TSI148_LCSR_ITAT_AS_A32;
585 break;
586 case VME_A64:
587 granularity = 0x10000;
588 addr |= TSI148_LCSR_ITAT_AS_A64;
589 break;
590 case VME_CRCSR:
591 case VME_USER1:
592 case VME_USER2:
593 case VME_USER3:
594 case VME_USER4:
595 default:
48d9356e 596 dev_err(tsi148_bridge->parent, "Invalid address space\n");
d22b8ed9
MW
597 return -EINVAL;
598 break;
599 }
600
601 /* Convert 64-bit variables to 2x 32-bit variables */
602 reg_split(vme_base, &vme_base_high, &vme_base_low);
603
604 /*
605 * Bound address is a valid address for the window, adjust
606 * accordingly
607 */
608 vme_bound = vme_base + size - granularity;
609 reg_split(vme_bound, &vme_bound_high, &vme_bound_low);
610 pci_offset = (unsigned long long)pci_base - vme_base;
611 reg_split(pci_offset, &pci_offset_high, &pci_offset_low);
612
613 if (vme_base_low & (granularity - 1)) {
48d9356e 614 dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n");
d22b8ed9
MW
615 return -EINVAL;
616 }
617 if (vme_bound_low & (granularity - 1)) {
48d9356e 618 dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n");
d22b8ed9
MW
619 return -EINVAL;
620 }
621 if (pci_offset_low & (granularity - 1)) {
48d9356e
MW
622 dev_err(tsi148_bridge->parent, "Invalid PCI Offset "
623 "alignment\n");
d22b8ed9
MW
624 return -EINVAL;
625 }
626
d22b8ed9 627 /* Disable while we are mucking around */
29848ac9 628 temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
629 TSI148_LCSR_OFFSET_ITAT);
630 temp_ctl &= ~TSI148_LCSR_ITAT_EN;
29848ac9 631 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
632 TSI148_LCSR_OFFSET_ITAT);
633
634 /* Setup mapping */
29848ac9 635 iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 636 TSI148_LCSR_OFFSET_ITSAU);
29848ac9 637 iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 638 TSI148_LCSR_OFFSET_ITSAL);
29848ac9 639 iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 640 TSI148_LCSR_OFFSET_ITEAU);
29848ac9 641 iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 642 TSI148_LCSR_OFFSET_ITEAL);
29848ac9 643 iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 644 TSI148_LCSR_OFFSET_ITOFU);
29848ac9 645 iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
646 TSI148_LCSR_OFFSET_ITOFL);
647
d22b8ed9
MW
648 /* Setup 2eSST speeds */
649 temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
650 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
651 case VME_2eSST160:
652 temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160;
653 break;
654 case VME_2eSST267:
655 temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267;
656 break;
657 case VME_2eSST320:
658 temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320;
659 break;
660 }
661
662 /* Setup cycle types */
663 temp_ctl &= ~(0x1F << 7);
664 if (cycle & VME_BLT)
665 temp_ctl |= TSI148_LCSR_ITAT_BLT;
666 if (cycle & VME_MBLT)
667 temp_ctl |= TSI148_LCSR_ITAT_MBLT;
668 if (cycle & VME_2eVME)
669 temp_ctl |= TSI148_LCSR_ITAT_2eVME;
670 if (cycle & VME_2eSST)
671 temp_ctl |= TSI148_LCSR_ITAT_2eSST;
672 if (cycle & VME_2eSSTB)
673 temp_ctl |= TSI148_LCSR_ITAT_2eSSTB;
674
675 /* Setup address space */
676 temp_ctl &= ~TSI148_LCSR_ITAT_AS_M;
677 temp_ctl |= addr;
678
679 temp_ctl &= ~0xF;
680 if (cycle & VME_SUPER)
681 temp_ctl |= TSI148_LCSR_ITAT_SUPR ;
682 if (cycle & VME_USER)
683 temp_ctl |= TSI148_LCSR_ITAT_NPRIV;
684 if (cycle & VME_PROG)
685 temp_ctl |= TSI148_LCSR_ITAT_PGM;
686 if (cycle & VME_DATA)
687 temp_ctl |= TSI148_LCSR_ITAT_DATA;
688
689 /* Write ctl reg without enable */
29848ac9 690 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
691 TSI148_LCSR_OFFSET_ITAT);
692
693 if (enabled)
694 temp_ctl |= TSI148_LCSR_ITAT_EN;
695
29848ac9 696 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
697 TSI148_LCSR_OFFSET_ITAT);
698
699 return 0;
700}
701
702/*
703 * Get slave window configuration.
d22b8ed9 704 */
5ade6c4d 705static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
d22b8ed9 706 unsigned long long *vme_base, unsigned long long *size,
6af04b06 707 dma_addr_t *pci_base, u32 *aspace, u32 *cycle)
d22b8ed9
MW
708{
709 unsigned int i, granularity = 0, ctl = 0;
710 unsigned int vme_base_low, vme_base_high;
711 unsigned int vme_bound_low, vme_bound_high;
712 unsigned int pci_offset_low, pci_offset_high;
713 unsigned long long vme_bound, pci_offset;
29848ac9 714 struct tsi148_driver *bridge;
d22b8ed9 715
29848ac9 716 bridge = image->parent->driver_priv;
d22b8ed9
MW
717
718 i = image->number;
719
720 /* Read registers */
29848ac9 721 ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
722 TSI148_LCSR_OFFSET_ITAT);
723
29848ac9 724 vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 725 TSI148_LCSR_OFFSET_ITSAU);
29848ac9 726 vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 727 TSI148_LCSR_OFFSET_ITSAL);
29848ac9 728 vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 729 TSI148_LCSR_OFFSET_ITEAU);
29848ac9 730 vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 731 TSI148_LCSR_OFFSET_ITEAL);
29848ac9 732 pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 733 TSI148_LCSR_OFFSET_ITOFU);
29848ac9 734 pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
735 TSI148_LCSR_OFFSET_ITOFL);
736
737 /* Convert 64-bit variables to 2x 32-bit variables */
738 reg_join(vme_base_high, vme_base_low, vme_base);
739 reg_join(vme_bound_high, vme_bound_low, &vme_bound);
740 reg_join(pci_offset_high, pci_offset_low, &pci_offset);
741
098ced8f 742 *pci_base = (dma_addr_t)(*vme_base + pci_offset);
d22b8ed9
MW
743
744 *enabled = 0;
745 *aspace = 0;
746 *cycle = 0;
747
748 if (ctl & TSI148_LCSR_ITAT_EN)
749 *enabled = 1;
750
751 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) {
752 granularity = 0x10;
753 *aspace |= VME_A16;
754 }
755 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) {
756 granularity = 0x1000;
757 *aspace |= VME_A24;
758 }
759 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) {
760 granularity = 0x10000;
761 *aspace |= VME_A32;
762 }
763 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) {
764 granularity = 0x10000;
765 *aspace |= VME_A64;
766 }
767
768 /* Need granularity before we set the size */
769 *size = (unsigned long long)((vme_bound - *vme_base) + granularity);
770
771
772 if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160)
773 *cycle |= VME_2eSST160;
774 if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267)
775 *cycle |= VME_2eSST267;
776 if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320)
777 *cycle |= VME_2eSST320;
778
779 if (ctl & TSI148_LCSR_ITAT_BLT)
780 *cycle |= VME_BLT;
781 if (ctl & TSI148_LCSR_ITAT_MBLT)
782 *cycle |= VME_MBLT;
783 if (ctl & TSI148_LCSR_ITAT_2eVME)
784 *cycle |= VME_2eVME;
785 if (ctl & TSI148_LCSR_ITAT_2eSST)
786 *cycle |= VME_2eSST;
787 if (ctl & TSI148_LCSR_ITAT_2eSSTB)
788 *cycle |= VME_2eSSTB;
789
790 if (ctl & TSI148_LCSR_ITAT_SUPR)
791 *cycle |= VME_SUPER;
792 if (ctl & TSI148_LCSR_ITAT_NPRIV)
793 *cycle |= VME_USER;
794 if (ctl & TSI148_LCSR_ITAT_PGM)
795 *cycle |= VME_PROG;
796 if (ctl & TSI148_LCSR_ITAT_DATA)
797 *cycle |= VME_DATA;
798
799 return 0;
800}
801
802/*
803 * Allocate and map PCI Resource
804 */
805static int tsi148_alloc_resource(struct vme_master_resource *image,
806 unsigned long long size)
807{
808 unsigned long long existing_size;
809 int retval = 0;
810 struct pci_dev *pdev;
29848ac9
MW
811 struct vme_bridge *tsi148_bridge;
812
813 tsi148_bridge = image->parent;
d22b8ed9 814
177581fa 815 pdev = to_pci_dev(tsi148_bridge->parent);
d22b8ed9 816
8fafb476
MW
817 existing_size = (unsigned long long)(image->bus_resource.end -
818 image->bus_resource.start);
d22b8ed9
MW
819
820 /* If the existing size is OK, return */
59c22904 821 if ((size != 0) && (existing_size == (size - 1)))
d22b8ed9
MW
822 return 0;
823
824 if (existing_size != 0) {
825 iounmap(image->kern_base);
826 image->kern_base = NULL;
794a8946 827 kfree(image->bus_resource.name);
886953e9
EC
828 release_resource(&image->bus_resource);
829 memset(&image->bus_resource, 0, sizeof(struct resource));
d22b8ed9
MW
830 }
831
59c22904 832 /* Exit here if size is zero */
7946328f 833 if (size == 0)
59c22904 834 return 0;
59c22904 835
8fafb476 836 if (image->bus_resource.name == NULL) {
0aa3f139 837 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC);
8fafb476 838 if (image->bus_resource.name == NULL) {
48d9356e
MW
839 dev_err(tsi148_bridge->parent, "Unable to allocate "
840 "memory for resource name\n");
d22b8ed9
MW
841 retval = -ENOMEM;
842 goto err_name;
843 }
844 }
845
8fafb476 846 sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name,
d22b8ed9
MW
847 image->number);
848
8fafb476
MW
849 image->bus_resource.start = 0;
850 image->bus_resource.end = (unsigned long)size;
851 image->bus_resource.flags = IORESOURCE_MEM;
d22b8ed9
MW
852
853 retval = pci_bus_alloc_resource(pdev->bus,
886953e9 854 &image->bus_resource, size, size, PCIBIOS_MIN_MEM,
d22b8ed9
MW
855 0, NULL, NULL);
856 if (retval) {
48d9356e
MW
857 dev_err(tsi148_bridge->parent, "Failed to allocate mem "
858 "resource for window %d size 0x%lx start 0x%lx\n",
d22b8ed9 859 image->number, (unsigned long)size,
8fafb476 860 (unsigned long)image->bus_resource.start);
d22b8ed9
MW
861 goto err_resource;
862 }
863
864 image->kern_base = ioremap_nocache(
8fafb476 865 image->bus_resource.start, size);
d22b8ed9 866 if (image->kern_base == NULL) {
48d9356e 867 dev_err(tsi148_bridge->parent, "Failed to remap resource\n");
d22b8ed9
MW
868 retval = -ENOMEM;
869 goto err_remap;
870 }
871
872 return 0;
873
d22b8ed9 874err_remap:
886953e9 875 release_resource(&image->bus_resource);
d22b8ed9 876err_resource:
8fafb476 877 kfree(image->bus_resource.name);
886953e9 878 memset(&image->bus_resource, 0, sizeof(struct resource));
d22b8ed9
MW
879err_name:
880 return retval;
881}
882
883/*
884 * Free and unmap PCI Resource
885 */
886static void tsi148_free_resource(struct vme_master_resource *image)
887{
888 iounmap(image->kern_base);
889 image->kern_base = NULL;
886953e9 890 release_resource(&image->bus_resource);
8fafb476 891 kfree(image->bus_resource.name);
886953e9 892 memset(&image->bus_resource, 0, sizeof(struct resource));
d22b8ed9
MW
893}
894
895/*
896 * Set the attributes of an outbound window.
897 */
5ade6c4d 898static int tsi148_master_set(struct vme_master_resource *image, int enabled,
6af04b06
MW
899 unsigned long long vme_base, unsigned long long size, u32 aspace,
900 u32 cycle, u32 dwidth)
d22b8ed9
MW
901{
902 int retval = 0;
903 unsigned int i;
904 unsigned int temp_ctl = 0;
905 unsigned int pci_base_low, pci_base_high;
906 unsigned int pci_bound_low, pci_bound_high;
907 unsigned int vme_offset_low, vme_offset_high;
908 unsigned long long pci_bound, vme_offset, pci_base;
48d9356e 909 struct vme_bridge *tsi148_bridge;
29848ac9 910 struct tsi148_driver *bridge;
226572b1
JS
911 struct pci_bus_region region;
912 struct pci_dev *pdev;
29848ac9 913
48d9356e
MW
914 tsi148_bridge = image->parent;
915
916 bridge = tsi148_bridge->driver_priv;
d22b8ed9 917
177581fa 918 pdev = to_pci_dev(tsi148_bridge->parent);
226572b1 919
d22b8ed9
MW
920 /* Verify input data */
921 if (vme_base & 0xFFFF) {
48d9356e
MW
922 dev_err(tsi148_bridge->parent, "Invalid VME Window "
923 "alignment\n");
d22b8ed9
MW
924 retval = -EINVAL;
925 goto err_window;
926 }
59c22904
MW
927
928 if ((size == 0) && (enabled != 0)) {
48d9356e
MW
929 dev_err(tsi148_bridge->parent, "Size must be non-zero for "
930 "enabled windows\n");
d22b8ed9
MW
931 retval = -EINVAL;
932 goto err_window;
933 }
934
886953e9 935 spin_lock(&image->lock);
d22b8ed9
MW
936
937 /* Let's allocate the resource here rather than further up the stack as
25985edc 938 * it avoids pushing loads of bus dependent stuff up the stack. If size
59c22904 939 * is zero, any existing resource will be freed.
d22b8ed9
MW
940 */
941 retval = tsi148_alloc_resource(image, size);
942 if (retval) {
886953e9 943 spin_unlock(&image->lock);
48d9356e 944 dev_err(tsi148_bridge->parent, "Unable to allocate memory for "
59c22904 945 "resource\n");
d22b8ed9
MW
946 goto err_res;
947 }
948
59c22904
MW
949 if (size == 0) {
950 pci_base = 0;
951 pci_bound = 0;
952 vme_offset = 0;
953 } else {
226572b1
JS
954 pcibios_resource_to_bus(pdev->bus, &region,
955 &image->bus_resource);
956 pci_base = region.start;
59c22904
MW
957
958 /*
959 * Bound address is a valid address for the window, adjust
960 * according to window granularity.
961 */
962 pci_bound = pci_base + (size - 0x10000);
963 vme_offset = vme_base - pci_base;
964 }
d22b8ed9
MW
965
966 /* Convert 64-bit variables to 2x 32-bit variables */
967 reg_split(pci_base, &pci_base_high, &pci_base_low);
968 reg_split(pci_bound, &pci_bound_high, &pci_bound_low);
969 reg_split(vme_offset, &vme_offset_high, &vme_offset_low);
970
971 if (pci_base_low & 0xFFFF) {
886953e9 972 spin_unlock(&image->lock);
48d9356e 973 dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n");
d22b8ed9
MW
974 retval = -EINVAL;
975 goto err_gran;
976 }
977 if (pci_bound_low & 0xFFFF) {
886953e9 978 spin_unlock(&image->lock);
48d9356e 979 dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n");
d22b8ed9
MW
980 retval = -EINVAL;
981 goto err_gran;
982 }
983 if (vme_offset_low & 0xFFFF) {
886953e9 984 spin_unlock(&image->lock);
48d9356e
MW
985 dev_err(tsi148_bridge->parent, "Invalid VME Offset "
986 "alignment\n");
d22b8ed9
MW
987 retval = -EINVAL;
988 goto err_gran;
989 }
990
991 i = image->number;
992
993 /* Disable while we are mucking around */
29848ac9 994 temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
995 TSI148_LCSR_OFFSET_OTAT);
996 temp_ctl &= ~TSI148_LCSR_OTAT_EN;
29848ac9 997 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
998 TSI148_LCSR_OFFSET_OTAT);
999
d22b8ed9
MW
1000 /* Setup 2eSST speeds */
1001 temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
1002 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
1003 case VME_2eSST160:
1004 temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160;
1005 break;
1006 case VME_2eSST267:
1007 temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267;
1008 break;
1009 case VME_2eSST320:
1010 temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320;
1011 break;
1012 }
1013
1014 /* Setup cycle types */
1015 if (cycle & VME_BLT) {
1016 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1017 temp_ctl |= TSI148_LCSR_OTAT_TM_BLT;
1018 }
1019 if (cycle & VME_MBLT) {
1020 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1021 temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT;
1022 }
1023 if (cycle & VME_2eVME) {
1024 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1025 temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME;
1026 }
1027 if (cycle & VME_2eSST) {
1028 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1029 temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
1030 }
1031 if (cycle & VME_2eSSTB) {
48d9356e
MW
1032 dev_warn(tsi148_bridge->parent, "Currently not setting "
1033 "Broadcast Select Registers\n");
d22b8ed9
MW
1034 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1035 temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
1036 }
1037
1038 /* Setup data width */
1039 temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M;
1040 switch (dwidth) {
1041 case VME_D16:
1042 temp_ctl |= TSI148_LCSR_OTAT_DBW_16;
1043 break;
1044 case VME_D32:
1045 temp_ctl |= TSI148_LCSR_OTAT_DBW_32;
1046 break;
1047 default:
886953e9 1048 spin_unlock(&image->lock);
48d9356e 1049 dev_err(tsi148_bridge->parent, "Invalid data width\n");
d22b8ed9
MW
1050 retval = -EINVAL;
1051 goto err_dwidth;
1052 }
1053
1054 /* Setup address space */
1055 temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M;
1056 switch (aspace) {
1057 case VME_A16:
1058 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16;
1059 break;
1060 case VME_A24:
1061 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24;
1062 break;
1063 case VME_A32:
1064 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32;
1065 break;
1066 case VME_A64:
1067 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64;
1068 break;
1069 case VME_CRCSR:
1070 temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR;
1071 break;
1072 case VME_USER1:
1073 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1;
1074 break;
1075 case VME_USER2:
1076 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2;
1077 break;
1078 case VME_USER3:
1079 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3;
1080 break;
1081 case VME_USER4:
1082 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4;
1083 break;
1084 default:
886953e9 1085 spin_unlock(&image->lock);
48d9356e 1086 dev_err(tsi148_bridge->parent, "Invalid address space\n");
d22b8ed9
MW
1087 retval = -EINVAL;
1088 goto err_aspace;
1089 break;
1090 }
1091
1092 temp_ctl &= ~(3<<4);
1093 if (cycle & VME_SUPER)
1094 temp_ctl |= TSI148_LCSR_OTAT_SUP;
1095 if (cycle & VME_PROG)
1096 temp_ctl |= TSI148_LCSR_OTAT_PGM;
1097
1098 /* Setup mapping */
29848ac9 1099 iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1100 TSI148_LCSR_OFFSET_OTSAU);
29848ac9 1101 iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1102 TSI148_LCSR_OFFSET_OTSAL);
29848ac9 1103 iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1104 TSI148_LCSR_OFFSET_OTEAU);
29848ac9 1105 iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1106 TSI148_LCSR_OFFSET_OTEAL);
29848ac9 1107 iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1108 TSI148_LCSR_OFFSET_OTOFU);
29848ac9 1109 iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1110 TSI148_LCSR_OFFSET_OTOFL);
1111
d22b8ed9 1112 /* Write ctl reg without enable */
29848ac9 1113 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1114 TSI148_LCSR_OFFSET_OTAT);
1115
1116 if (enabled)
1117 temp_ctl |= TSI148_LCSR_OTAT_EN;
1118
29848ac9 1119 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1120 TSI148_LCSR_OFFSET_OTAT);
1121
886953e9 1122 spin_unlock(&image->lock);
d22b8ed9
MW
1123 return 0;
1124
1125err_aspace:
1126err_dwidth:
1127err_gran:
1128 tsi148_free_resource(image);
1129err_res:
1130err_window:
1131 return retval;
1132
1133}
1134
1135/*
1136 * Set the attributes of an outbound window.
1137 *
1138 * XXX Not parsing prefetch information.
1139 */
5ade6c4d 1140static int __tsi148_master_get(struct vme_master_resource *image, int *enabled,
6af04b06
MW
1141 unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
1142 u32 *cycle, u32 *dwidth)
d22b8ed9
MW
1143{
1144 unsigned int i, ctl;
1145 unsigned int pci_base_low, pci_base_high;
1146 unsigned int pci_bound_low, pci_bound_high;
1147 unsigned int vme_offset_low, vme_offset_high;
1148
1149 unsigned long long pci_base, pci_bound, vme_offset;
29848ac9
MW
1150 struct tsi148_driver *bridge;
1151
1152 bridge = image->parent->driver_priv;
d22b8ed9
MW
1153
1154 i = image->number;
1155
29848ac9 1156 ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1157 TSI148_LCSR_OFFSET_OTAT);
1158
29848ac9 1159 pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1160 TSI148_LCSR_OFFSET_OTSAU);
29848ac9 1161 pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1162 TSI148_LCSR_OFFSET_OTSAL);
29848ac9 1163 pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1164 TSI148_LCSR_OFFSET_OTEAU);
29848ac9 1165 pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1166 TSI148_LCSR_OFFSET_OTEAL);
29848ac9 1167 vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1168 TSI148_LCSR_OFFSET_OTOFU);
29848ac9 1169 vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1170 TSI148_LCSR_OFFSET_OTOFL);
1171
1172 /* Convert 64-bit variables to 2x 32-bit variables */
1173 reg_join(pci_base_high, pci_base_low, &pci_base);
1174 reg_join(pci_bound_high, pci_bound_low, &pci_bound);
1175 reg_join(vme_offset_high, vme_offset_low, &vme_offset);
1176
1177 *vme_base = pci_base + vme_offset;
1178 *size = (unsigned long long)(pci_bound - pci_base) + 0x10000;
1179
1180 *enabled = 0;
1181 *aspace = 0;
1182 *cycle = 0;
1183 *dwidth = 0;
1184
1185 if (ctl & TSI148_LCSR_OTAT_EN)
1186 *enabled = 1;
1187
1188 /* Setup address space */
1189 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16)
1190 *aspace |= VME_A16;
1191 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24)
1192 *aspace |= VME_A24;
1193 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32)
1194 *aspace |= VME_A32;
1195 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64)
1196 *aspace |= VME_A64;
1197 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR)
1198 *aspace |= VME_CRCSR;
1199 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1)
1200 *aspace |= VME_USER1;
1201 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2)
1202 *aspace |= VME_USER2;
1203 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3)
1204 *aspace |= VME_USER3;
1205 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4)
1206 *aspace |= VME_USER4;
1207
1208 /* Setup 2eSST speeds */
1209 if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160)
1210 *cycle |= VME_2eSST160;
1211 if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267)
1212 *cycle |= VME_2eSST267;
1213 if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320)
1214 *cycle |= VME_2eSST320;
1215
1216 /* Setup cycle types */
7946328f 1217 if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_SCT)
d22b8ed9 1218 *cycle |= VME_SCT;
7946328f 1219 if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_BLT)
d22b8ed9 1220 *cycle |= VME_BLT;
7946328f 1221 if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_MBLT)
d22b8ed9 1222 *cycle |= VME_MBLT;
7946328f 1223 if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eVME)
d22b8ed9 1224 *cycle |= VME_2eVME;
7946328f 1225 if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSST)
d22b8ed9 1226 *cycle |= VME_2eSST;
7946328f 1227 if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSSTB)
d22b8ed9
MW
1228 *cycle |= VME_2eSSTB;
1229
1230 if (ctl & TSI148_LCSR_OTAT_SUP)
1231 *cycle |= VME_SUPER;
1232 else
1233 *cycle |= VME_USER;
1234
1235 if (ctl & TSI148_LCSR_OTAT_PGM)
1236 *cycle |= VME_PROG;
1237 else
1238 *cycle |= VME_DATA;
1239
1240 /* Setup data width */
1241 if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16)
1242 *dwidth = VME_D16;
1243 if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32)
1244 *dwidth = VME_D32;
1245
1246 return 0;
1247}
1248
1249
5ade6c4d 1250static int tsi148_master_get(struct vme_master_resource *image, int *enabled,
6af04b06
MW
1251 unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
1252 u32 *cycle, u32 *dwidth)
d22b8ed9
MW
1253{
1254 int retval;
1255
886953e9 1256 spin_lock(&image->lock);
d22b8ed9
MW
1257
1258 retval = __tsi148_master_get(image, enabled, vme_base, size, aspace,
1259 cycle, dwidth);
1260
886953e9 1261 spin_unlock(&image->lock);
d22b8ed9
MW
1262
1263 return retval;
1264}
1265
5ade6c4d 1266static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
d22b8ed9
MW
1267 size_t count, loff_t offset)
1268{
1269 int retval, enabled;
1270 unsigned long long vme_base, size;
6af04b06 1271 u32 aspace, cycle, dwidth;
d22b8ed9 1272 struct vme_bus_error *vme_err = NULL;
29848ac9 1273 struct vme_bridge *tsi148_bridge;
4e8764d9 1274 void __iomem *addr = image->kern_base + offset;
363e2e6f
MW
1275 unsigned int done = 0;
1276 unsigned int count32;
29848ac9
MW
1277
1278 tsi148_bridge = image->parent;
d22b8ed9 1279
886953e9 1280 spin_lock(&image->lock);
d22b8ed9 1281
363e2e6f 1282 /* The following code handles VME address alignment. We cannot use
a2a720e1
MW
1283 * memcpy_xxx here because it may cut data transfers in to 8-bit
1284 * cycles when D16 or D32 cycles are required on the VME bus.
363e2e6f
MW
1285 * On the other hand, the bridge itself assures that the maximum data
1286 * cycle configured for the transfer is used and splits it
1287 * automatically for non-aligned addresses, so we don't want the
1288 * overhead of needlessly forcing small transfers for the entire cycle.
1289 */
1290 if ((uintptr_t)addr & 0x1) {
1291 *(u8 *)buf = ioread8(addr);
1292 done += 1;
1293 if (done == count)
1294 goto out;
1295 }
f0342e66 1296 if ((uintptr_t)(addr + done) & 0x2) {
363e2e6f
MW
1297 if ((count - done) < 2) {
1298 *(u8 *)(buf + done) = ioread8(addr + done);
1299 done += 1;
1300 goto out;
1301 } else {
1302 *(u16 *)(buf + done) = ioread16(addr + done);
1303 done += 2;
1304 }
1305 }
1306
1307 count32 = (count - done) & ~0x3;
a2a720e1
MW
1308 while (done < count32) {
1309 *(u32 *)(buf + done) = ioread32(addr + done);
1310 done += 4;
363e2e6f
MW
1311 }
1312
1313 if ((count - done) & 0x2) {
1314 *(u16 *)(buf + done) = ioread16(addr + done);
1315 done += 2;
1316 }
1317 if ((count - done) & 0x1) {
1318 *(u8 *)(buf + done) = ioread8(addr + done);
1319 done += 1;
1320 }
1321
1322out:
d22b8ed9
MW
1323 retval = count;
1324
1325 if (!err_chk)
1326 goto skip_chk;
1327
1328 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
1329 &dwidth);
1330
29848ac9
MW
1331 vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
1332 count);
7946328f 1333 if (vme_err != NULL) {
d22b8ed9
MW
1334 dev_err(image->parent->parent, "First VME read error detected "
1335 "an at address 0x%llx\n", vme_err->address);
1336 retval = vme_err->address - (vme_base + offset);
1337 /* Clear down save errors in this address range */
29848ac9
MW
1338 tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
1339 count);
d22b8ed9
MW
1340 }
1341
1342skip_chk:
886953e9 1343 spin_unlock(&image->lock);
d22b8ed9
MW
1344
1345 return retval;
1346}
1347
1348
5ade6c4d 1349static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
d22b8ed9
MW
1350 size_t count, loff_t offset)
1351{
1352 int retval = 0, enabled;
1353 unsigned long long vme_base, size;
6af04b06 1354 u32 aspace, cycle, dwidth;
4e8764d9 1355 void __iomem *addr = image->kern_base + offset;
363e2e6f
MW
1356 unsigned int done = 0;
1357 unsigned int count32;
d22b8ed9
MW
1358
1359 struct vme_bus_error *vme_err = NULL;
29848ac9
MW
1360 struct vme_bridge *tsi148_bridge;
1361 struct tsi148_driver *bridge;
1362
1363 tsi148_bridge = image->parent;
1364
1365 bridge = tsi148_bridge->driver_priv;
d22b8ed9 1366
886953e9 1367 spin_lock(&image->lock);
d22b8ed9 1368
363e2e6f 1369 /* Here we apply for the same strategy we do in master_read
a2a720e1 1370 * function in order to assure the correct cycles.
363e2e6f
MW
1371 */
1372 if ((uintptr_t)addr & 0x1) {
1373 iowrite8(*(u8 *)buf, addr);
1374 done += 1;
1375 if (done == count)
1376 goto out;
1377 }
f0342e66 1378 if ((uintptr_t)(addr + done) & 0x2) {
363e2e6f
MW
1379 if ((count - done) < 2) {
1380 iowrite8(*(u8 *)(buf + done), addr + done);
1381 done += 1;
1382 goto out;
1383 } else {
1384 iowrite16(*(u16 *)(buf + done), addr + done);
1385 done += 2;
1386 }
1387 }
1388
1389 count32 = (count - done) & ~0x3;
a2a720e1
MW
1390 while (done < count32) {
1391 iowrite32(*(u32 *)(buf + done), addr + done);
1392 done += 4;
363e2e6f
MW
1393 }
1394
1395 if ((count - done) & 0x2) {
1396 iowrite16(*(u16 *)(buf + done), addr + done);
1397 done += 2;
1398 }
1399 if ((count - done) & 0x1) {
1400 iowrite8(*(u8 *)(buf + done), addr + done);
1401 done += 1;
1402 }
1403
1404out:
d22b8ed9
MW
1405 retval = count;
1406
1407 /*
1408 * Writes are posted. We need to do a read on the VME bus to flush out
25985edc 1409 * all of the writes before we check for errors. We can't guarantee
d22b8ed9
MW
1410 * that reading the data we have just written is safe. It is believed
1411 * that there isn't any read, write re-ordering, so we can read any
1412 * location in VME space, so lets read the Device ID from the tsi148's
1413 * own registers as mapped into CR/CSR space.
1414 *
1415 * We check for saved errors in the written address range/space.
1416 */
1417
1418 if (!err_chk)
1419 goto skip_chk;
1420
1421 /*
1422 * Get window info first, to maximise the time that the buffers may
1423 * fluch on their own
1424 */
1425 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
1426 &dwidth);
1427
29848ac9 1428 ioread16(bridge->flush_image->kern_base + 0x7F000);
d22b8ed9 1429
29848ac9
MW
1430 vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
1431 count);
7946328f 1432 if (vme_err != NULL) {
48d9356e
MW
1433 dev_warn(tsi148_bridge->parent, "First VME write error detected"
1434 " an at address 0x%llx\n", vme_err->address);
d22b8ed9
MW
1435 retval = vme_err->address - (vme_base + offset);
1436 /* Clear down save errors in this address range */
29848ac9
MW
1437 tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
1438 count);
d22b8ed9
MW
1439 }
1440
1441skip_chk:
886953e9 1442 spin_unlock(&image->lock);
d22b8ed9
MW
1443
1444 return retval;
1445}
1446
1447/*
1448 * Perform an RMW cycle on the VME bus.
1449 *
1450 * Requires a previously configured master window, returns final value.
1451 */
5ade6c4d 1452static unsigned int tsi148_master_rmw(struct vme_master_resource *image,
d22b8ed9
MW
1453 unsigned int mask, unsigned int compare, unsigned int swap,
1454 loff_t offset)
1455{
1456 unsigned long long pci_addr;
1457 unsigned int pci_addr_high, pci_addr_low;
1458 u32 tmp, result;
1459 int i;
29848ac9 1460 struct tsi148_driver *bridge;
d22b8ed9 1461
29848ac9 1462 bridge = image->parent->driver_priv;
d22b8ed9
MW
1463
1464 /* Find the PCI address that maps to the desired VME address */
1465 i = image->number;
1466
1467 /* Locking as we can only do one of these at a time */
886953e9 1468 mutex_lock(&bridge->vme_rmw);
d22b8ed9
MW
1469
1470 /* Lock image */
886953e9 1471 spin_lock(&image->lock);
d22b8ed9 1472
29848ac9 1473 pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1474 TSI148_LCSR_OFFSET_OTSAU);
29848ac9 1475 pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1476 TSI148_LCSR_OFFSET_OTSAL);
1477
1478 reg_join(pci_addr_high, pci_addr_low, &pci_addr);
1479 reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
1480
1481 /* Configure registers */
29848ac9
MW
1482 iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN);
1483 iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC);
1484 iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS);
1485 iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU);
1486 iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL);
d22b8ed9
MW
1487
1488 /* Enable RMW */
29848ac9 1489 tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9 1490 tmp |= TSI148_LCSR_VMCTRL_RMWEN;
29848ac9 1491 iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9
MW
1492
1493 /* Kick process off with a read to the required address. */
1494 result = ioread32be(image->kern_base + offset);
1495
1496 /* Disable RMW */
29848ac9 1497 tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9 1498 tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
29848ac9 1499 iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9 1500
886953e9 1501 spin_unlock(&image->lock);
d22b8ed9 1502
886953e9 1503 mutex_unlock(&bridge->vme_rmw);
d22b8ed9
MW
1504
1505 return result;
1506}
1507
ac1a4f2c 1508static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr,
6af04b06 1509 u32 aspace, u32 cycle, u32 dwidth)
d22b8ed9 1510{
ac1a4f2c
MW
1511 u32 val;
1512
1513 val = be32_to_cpu(*attr);
1514
d22b8ed9
MW
1515 /* Setup 2eSST speeds */
1516 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
1517 case VME_2eSST160:
ac1a4f2c 1518 val |= TSI148_LCSR_DSAT_2eSSTM_160;
d22b8ed9
MW
1519 break;
1520 case VME_2eSST267:
ac1a4f2c 1521 val |= TSI148_LCSR_DSAT_2eSSTM_267;
d22b8ed9
MW
1522 break;
1523 case VME_2eSST320:
ac1a4f2c 1524 val |= TSI148_LCSR_DSAT_2eSSTM_320;
d22b8ed9
MW
1525 break;
1526 }
1527
1528 /* Setup cycle types */
7946328f 1529 if (cycle & VME_SCT)
ac1a4f2c 1530 val |= TSI148_LCSR_DSAT_TM_SCT;
7946328f
MW
1531
1532 if (cycle & VME_BLT)
ac1a4f2c 1533 val |= TSI148_LCSR_DSAT_TM_BLT;
7946328f
MW
1534
1535 if (cycle & VME_MBLT)
ac1a4f2c 1536 val |= TSI148_LCSR_DSAT_TM_MBLT;
7946328f
MW
1537
1538 if (cycle & VME_2eVME)
ac1a4f2c 1539 val |= TSI148_LCSR_DSAT_TM_2eVME;
7946328f
MW
1540
1541 if (cycle & VME_2eSST)
ac1a4f2c 1542 val |= TSI148_LCSR_DSAT_TM_2eSST;
7946328f 1543
d22b8ed9 1544 if (cycle & VME_2eSSTB) {
48d9356e
MW
1545 dev_err(dev, "Currently not setting Broadcast Select "
1546 "Registers\n");
ac1a4f2c 1547 val |= TSI148_LCSR_DSAT_TM_2eSSTB;
d22b8ed9
MW
1548 }
1549
1550 /* Setup data width */
1551 switch (dwidth) {
1552 case VME_D16:
ac1a4f2c 1553 val |= TSI148_LCSR_DSAT_DBW_16;
d22b8ed9
MW
1554 break;
1555 case VME_D32:
ac1a4f2c 1556 val |= TSI148_LCSR_DSAT_DBW_32;
d22b8ed9
MW
1557 break;
1558 default:
48d9356e 1559 dev_err(dev, "Invalid data width\n");
d22b8ed9
MW
1560 return -EINVAL;
1561 }
1562
1563 /* Setup address space */
1564 switch (aspace) {
1565 case VME_A16:
ac1a4f2c 1566 val |= TSI148_LCSR_DSAT_AMODE_A16;
d22b8ed9
MW
1567 break;
1568 case VME_A24:
ac1a4f2c 1569 val |= TSI148_LCSR_DSAT_AMODE_A24;
d22b8ed9
MW
1570 break;
1571 case VME_A32:
ac1a4f2c 1572 val |= TSI148_LCSR_DSAT_AMODE_A32;
d22b8ed9
MW
1573 break;
1574 case VME_A64:
ac1a4f2c 1575 val |= TSI148_LCSR_DSAT_AMODE_A64;
d22b8ed9
MW
1576 break;
1577 case VME_CRCSR:
ac1a4f2c 1578 val |= TSI148_LCSR_DSAT_AMODE_CRCSR;
d22b8ed9
MW
1579 break;
1580 case VME_USER1:
ac1a4f2c 1581 val |= TSI148_LCSR_DSAT_AMODE_USER1;
d22b8ed9
MW
1582 break;
1583 case VME_USER2:
ac1a4f2c 1584 val |= TSI148_LCSR_DSAT_AMODE_USER2;
d22b8ed9
MW
1585 break;
1586 case VME_USER3:
ac1a4f2c 1587 val |= TSI148_LCSR_DSAT_AMODE_USER3;
d22b8ed9
MW
1588 break;
1589 case VME_USER4:
ac1a4f2c 1590 val |= TSI148_LCSR_DSAT_AMODE_USER4;
d22b8ed9
MW
1591 break;
1592 default:
48d9356e 1593 dev_err(dev, "Invalid address space\n");
d22b8ed9
MW
1594 return -EINVAL;
1595 break;
1596 }
1597
1598 if (cycle & VME_SUPER)
ac1a4f2c 1599 val |= TSI148_LCSR_DSAT_SUP;
d22b8ed9 1600 if (cycle & VME_PROG)
ac1a4f2c
MW
1601 val |= TSI148_LCSR_DSAT_PGM;
1602
1603 *attr = cpu_to_be32(val);
d22b8ed9
MW
1604
1605 return 0;
1606}
1607
ac1a4f2c 1608static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr,
6af04b06 1609 u32 aspace, u32 cycle, u32 dwidth)
d22b8ed9 1610{
ac1a4f2c
MW
1611 u32 val;
1612
1613 val = be32_to_cpu(*attr);
1614
d22b8ed9
MW
1615 /* Setup 2eSST speeds */
1616 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
1617 case VME_2eSST160:
ac1a4f2c 1618 val |= TSI148_LCSR_DDAT_2eSSTM_160;
d22b8ed9
MW
1619 break;
1620 case VME_2eSST267:
ac1a4f2c 1621 val |= TSI148_LCSR_DDAT_2eSSTM_267;
d22b8ed9
MW
1622 break;
1623 case VME_2eSST320:
ac1a4f2c 1624 val |= TSI148_LCSR_DDAT_2eSSTM_320;
d22b8ed9
MW
1625 break;
1626 }
1627
1628 /* Setup cycle types */
7946328f 1629 if (cycle & VME_SCT)
ac1a4f2c 1630 val |= TSI148_LCSR_DDAT_TM_SCT;
7946328f
MW
1631
1632 if (cycle & VME_BLT)
ac1a4f2c 1633 val |= TSI148_LCSR_DDAT_TM_BLT;
7946328f
MW
1634
1635 if (cycle & VME_MBLT)
ac1a4f2c 1636 val |= TSI148_LCSR_DDAT_TM_MBLT;
7946328f
MW
1637
1638 if (cycle & VME_2eVME)
ac1a4f2c 1639 val |= TSI148_LCSR_DDAT_TM_2eVME;
7946328f
MW
1640
1641 if (cycle & VME_2eSST)
ac1a4f2c 1642 val |= TSI148_LCSR_DDAT_TM_2eSST;
7946328f 1643
d22b8ed9 1644 if (cycle & VME_2eSSTB) {
48d9356e
MW
1645 dev_err(dev, "Currently not setting Broadcast Select "
1646 "Registers\n");
ac1a4f2c 1647 val |= TSI148_LCSR_DDAT_TM_2eSSTB;
d22b8ed9
MW
1648 }
1649
1650 /* Setup data width */
1651 switch (dwidth) {
1652 case VME_D16:
ac1a4f2c 1653 val |= TSI148_LCSR_DDAT_DBW_16;
d22b8ed9
MW
1654 break;
1655 case VME_D32:
ac1a4f2c 1656 val |= TSI148_LCSR_DDAT_DBW_32;
d22b8ed9
MW
1657 break;
1658 default:
48d9356e 1659 dev_err(dev, "Invalid data width\n");
d22b8ed9
MW
1660 return -EINVAL;
1661 }
1662
1663 /* Setup address space */
1664 switch (aspace) {
1665 case VME_A16:
ac1a4f2c 1666 val |= TSI148_LCSR_DDAT_AMODE_A16;
d22b8ed9
MW
1667 break;
1668 case VME_A24:
ac1a4f2c 1669 val |= TSI148_LCSR_DDAT_AMODE_A24;
d22b8ed9
MW
1670 break;
1671 case VME_A32:
ac1a4f2c 1672 val |= TSI148_LCSR_DDAT_AMODE_A32;
d22b8ed9
MW
1673 break;
1674 case VME_A64:
ac1a4f2c 1675 val |= TSI148_LCSR_DDAT_AMODE_A64;
d22b8ed9
MW
1676 break;
1677 case VME_CRCSR:
ac1a4f2c 1678 val |= TSI148_LCSR_DDAT_AMODE_CRCSR;
d22b8ed9
MW
1679 break;
1680 case VME_USER1:
ac1a4f2c 1681 val |= TSI148_LCSR_DDAT_AMODE_USER1;
d22b8ed9
MW
1682 break;
1683 case VME_USER2:
ac1a4f2c 1684 val |= TSI148_LCSR_DDAT_AMODE_USER2;
d22b8ed9
MW
1685 break;
1686 case VME_USER3:
ac1a4f2c 1687 val |= TSI148_LCSR_DDAT_AMODE_USER3;
d22b8ed9
MW
1688 break;
1689 case VME_USER4:
ac1a4f2c 1690 val |= TSI148_LCSR_DDAT_AMODE_USER4;
d22b8ed9
MW
1691 break;
1692 default:
48d9356e 1693 dev_err(dev, "Invalid address space\n");
d22b8ed9
MW
1694 return -EINVAL;
1695 break;
1696 }
1697
1698 if (cycle & VME_SUPER)
ac1a4f2c 1699 val |= TSI148_LCSR_DDAT_SUP;
d22b8ed9 1700 if (cycle & VME_PROG)
ac1a4f2c
MW
1701 val |= TSI148_LCSR_DDAT_PGM;
1702
1703 *attr = cpu_to_be32(val);
d22b8ed9
MW
1704
1705 return 0;
1706}
1707
1708/*
1709 * Add a link list descriptor to the list
ac1a4f2c
MW
1710 *
1711 * Note: DMA engine expects the DMA descriptor to be big endian.
d22b8ed9 1712 */
5ade6c4d
EC
1713static int tsi148_dma_list_add(struct vme_dma_list *list,
1714 struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count)
d22b8ed9
MW
1715{
1716 struct tsi148_dma_entry *entry, *prev;
ac1a4f2c 1717 u32 address_high, address_low, val;
d22b8ed9
MW
1718 struct vme_dma_pattern *pattern_attr;
1719 struct vme_dma_pci *pci_attr;
1720 struct vme_dma_vme *vme_attr;
d22b8ed9 1721 int retval = 0;
48d9356e
MW
1722 struct vme_bridge *tsi148_bridge;
1723
1724 tsi148_bridge = list->parent->parent;
d22b8ed9 1725
bb9ea89e 1726 /* Descriptor must be aligned on 64-bit boundaries */
7946328f 1727 entry = kmalloc(sizeof(struct tsi148_dma_entry), GFP_KERNEL);
d22b8ed9 1728 if (entry == NULL) {
48d9356e
MW
1729 dev_err(tsi148_bridge->parent, "Failed to allocate memory for "
1730 "dma resource structure\n");
d22b8ed9
MW
1731 retval = -ENOMEM;
1732 goto err_mem;
1733 }
1734
1735 /* Test descriptor alignment */
886953e9 1736 if ((unsigned long)&entry->descriptor & 0x7) {
48d9356e
MW
1737 dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 "
1738 "byte boundary as required: %p\n",
886953e9 1739 &entry->descriptor);
d22b8ed9
MW
1740 retval = -EINVAL;
1741 goto err_align;
1742 }
1743
1744 /* Given we are going to fill out the structure, we probably don't
1745 * need to zero it, but better safe than sorry for now.
1746 */
886953e9 1747 memset(&entry->descriptor, 0, sizeof(struct tsi148_dma_descriptor));
d22b8ed9
MW
1748
1749 /* Fill out source part */
1750 switch (src->type) {
1751 case VME_DMA_PATTERN:
c4d82fbb 1752 pattern_attr = src->private;
d22b8ed9 1753
ac1a4f2c
MW
1754 entry->descriptor.dsal = cpu_to_be32(pattern_attr->pattern);
1755
1756 val = TSI148_LCSR_DSAT_TYP_PAT;
1757
d22b8ed9 1758 /* Default behaviour is 32 bit pattern */
7946328f 1759 if (pattern_attr->type & VME_DMA_PATTERN_BYTE)
ac1a4f2c 1760 val |= TSI148_LCSR_DSAT_PSZ;
7946328f 1761
d22b8ed9 1762 /* It seems that the default behaviour is to increment */
7946328f 1763 if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0)
ac1a4f2c
MW
1764 val |= TSI148_LCSR_DSAT_NIN;
1765 entry->descriptor.dsat = cpu_to_be32(val);
d22b8ed9
MW
1766 break;
1767 case VME_DMA_PCI:
c4d82fbb 1768 pci_attr = src->private;
d22b8ed9
MW
1769
1770 reg_split((unsigned long long)pci_attr->address, &address_high,
1771 &address_low);
ac1a4f2c
MW
1772 entry->descriptor.dsau = cpu_to_be32(address_high);
1773 entry->descriptor.dsal = cpu_to_be32(address_low);
1774 entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_PCI);
d22b8ed9
MW
1775 break;
1776 case VME_DMA_VME:
c4d82fbb 1777 vme_attr = src->private;
d22b8ed9
MW
1778
1779 reg_split((unsigned long long)vme_attr->address, &address_high,
1780 &address_low);
ac1a4f2c
MW
1781 entry->descriptor.dsau = cpu_to_be32(address_high);
1782 entry->descriptor.dsal = cpu_to_be32(address_low);
1783 entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_VME);
d22b8ed9
MW
1784
1785 retval = tsi148_dma_set_vme_src_attributes(
886953e9 1786 tsi148_bridge->parent, &entry->descriptor.dsat,
48d9356e 1787 vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth);
7946328f 1788 if (retval < 0)
d22b8ed9
MW
1789 goto err_source;
1790 break;
1791 default:
48d9356e 1792 dev_err(tsi148_bridge->parent, "Invalid source type\n");
d22b8ed9
MW
1793 retval = -EINVAL;
1794 goto err_source;
1795 break;
1796 }
1797
1798 /* Assume last link - this will be over-written by adding another */
ac1a4f2c
MW
1799 entry->descriptor.dnlau = cpu_to_be32(0);
1800 entry->descriptor.dnlal = cpu_to_be32(TSI148_LCSR_DNLAL_LLA);
d22b8ed9
MW
1801
1802 /* Fill out destination part */
1803 switch (dest->type) {
1804 case VME_DMA_PCI:
c4d82fbb 1805 pci_attr = dest->private;
d22b8ed9
MW
1806
1807 reg_split((unsigned long long)pci_attr->address, &address_high,
1808 &address_low);
ac1a4f2c
MW
1809 entry->descriptor.ddau = cpu_to_be32(address_high);
1810 entry->descriptor.ddal = cpu_to_be32(address_low);
1811 entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_PCI);
d22b8ed9
MW
1812 break;
1813 case VME_DMA_VME:
c4d82fbb 1814 vme_attr = dest->private;
d22b8ed9
MW
1815
1816 reg_split((unsigned long long)vme_attr->address, &address_high,
1817 &address_low);
ac1a4f2c
MW
1818 entry->descriptor.ddau = cpu_to_be32(address_high);
1819 entry->descriptor.ddal = cpu_to_be32(address_low);
1820 entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_VME);
d22b8ed9
MW
1821
1822 retval = tsi148_dma_set_vme_dest_attributes(
886953e9 1823 tsi148_bridge->parent, &entry->descriptor.ddat,
48d9356e 1824 vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth);
7946328f 1825 if (retval < 0)
d22b8ed9
MW
1826 goto err_dest;
1827 break;
1828 default:
48d9356e 1829 dev_err(tsi148_bridge->parent, "Invalid destination type\n");
d22b8ed9
MW
1830 retval = -EINVAL;
1831 goto err_dest;
1832 break;
1833 }
1834
1835 /* Fill out count */
ac1a4f2c 1836 entry->descriptor.dcnt = cpu_to_be32((u32)count);
d22b8ed9
MW
1837
1838 /* Add to list */
886953e9 1839 list_add_tail(&entry->list, &list->entries);
d22b8ed9
MW
1840
1841 /* Fill out previous descriptors "Next Address" */
886953e9 1842 if (entry->list.prev != &list->entries) {
d22b8ed9
MW
1843 prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
1844 list);
1845 /* We need the bus address for the pointer */
3abc48ae
MW
1846 entry->dma_handle = dma_map_single(tsi148_bridge->parent,
1847 &entry->descriptor,
1848 sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
1849
ac1a4f2c
MW
1850 reg_split((unsigned long long)entry->dma_handle, &address_high,
1851 &address_low);
1852 entry->descriptor.dnlau = cpu_to_be32(address_high);
1853 entry->descriptor.dnlal = cpu_to_be32(address_low);
1854
d22b8ed9
MW
1855 }
1856
1857 return 0;
1858
1859err_dest:
1860err_source:
1861err_align:
1862 kfree(entry);
1863err_mem:
1864 return retval;
1865}
1866
1867/*
1868 * Check to see if the provided DMA channel is busy.
1869 */
29848ac9 1870static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
d22b8ed9
MW
1871{
1872 u32 tmp;
29848ac9
MW
1873 struct tsi148_driver *bridge;
1874
1875 bridge = tsi148_bridge->driver_priv;
d22b8ed9 1876
29848ac9 1877 tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
d22b8ed9
MW
1878 TSI148_LCSR_OFFSET_DSTA);
1879
1880 if (tmp & TSI148_LCSR_DSTA_BSY)
1881 return 0;
1882 else
1883 return 1;
1884
1885}
1886
1887/*
1888 * Execute a previously generated link list
1889 *
1890 * XXX Need to provide control register configuration.
1891 */
5ade6c4d 1892static int tsi148_dma_list_exec(struct vme_dma_list *list)
d22b8ed9
MW
1893{
1894 struct vme_dma_resource *ctrlr;
1895 int channel, retval = 0;
1896 struct tsi148_dma_entry *entry;
d22b8ed9
MW
1897 u32 bus_addr_high, bus_addr_low;
1898 u32 val, dctlreg = 0;
48d9356e 1899 struct vme_bridge *tsi148_bridge;
29848ac9 1900 struct tsi148_driver *bridge;
d22b8ed9
MW
1901
1902 ctrlr = list->parent;
1903
48d9356e
MW
1904 tsi148_bridge = ctrlr->parent;
1905
1906 bridge = tsi148_bridge->driver_priv;
29848ac9 1907
886953e9 1908 mutex_lock(&ctrlr->mtx);
d22b8ed9
MW
1909
1910 channel = ctrlr->number;
1911
886953e9 1912 if (!list_empty(&ctrlr->running)) {
d22b8ed9
MW
1913 /*
1914 * XXX We have an active DMA transfer and currently haven't
1915 * sorted out the mechanism for "pending" DMA transfers.
1916 * Return busy.
1917 */
1918 /* Need to add to pending here */
886953e9 1919 mutex_unlock(&ctrlr->mtx);
d22b8ed9
MW
1920 return -EBUSY;
1921 } else {
886953e9 1922 list_add(&list->list, &ctrlr->running);
d22b8ed9 1923 }
d22b8ed9
MW
1924
1925 /* Get first bus address and write into registers */
886953e9 1926 entry = list_first_entry(&list->entries, struct tsi148_dma_entry,
d22b8ed9
MW
1927 list);
1928
3abc48ae
MW
1929 entry->dma_handle = dma_map_single(tsi148_bridge->parent,
1930 &entry->descriptor,
1931 sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
d22b8ed9 1932
886953e9 1933 mutex_unlock(&ctrlr->mtx);
d22b8ed9 1934
3abc48ae 1935 reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low);
d22b8ed9 1936
29848ac9 1937 iowrite32be(bus_addr_high, bridge->base +
d22b8ed9 1938 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
29848ac9 1939 iowrite32be(bus_addr_low, bridge->base +
d22b8ed9
MW
1940 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
1941
ac1a4f2c
MW
1942 dctlreg = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
1943 TSI148_LCSR_OFFSET_DCTL);
1944
d22b8ed9 1945 /* Start the operation */
29848ac9 1946 iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
d22b8ed9
MW
1947 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
1948
29848ac9
MW
1949 wait_event_interruptible(bridge->dma_queue[channel],
1950 tsi148_dma_busy(ctrlr->parent, channel));
ac1a4f2c 1951
d22b8ed9
MW
1952 /*
1953 * Read status register, this register is valid until we kick off a
1954 * new transfer.
1955 */
29848ac9 1956 val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
d22b8ed9
MW
1957 TSI148_LCSR_OFFSET_DSTA);
1958
1959 if (val & TSI148_LCSR_DSTA_VBE) {
48d9356e 1960 dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val);
d22b8ed9
MW
1961 retval = -EIO;
1962 }
1963
1964 /* Remove list from running list */
886953e9
EC
1965 mutex_lock(&ctrlr->mtx);
1966 list_del(&list->list);
1967 mutex_unlock(&ctrlr->mtx);
d22b8ed9
MW
1968
1969 return retval;
1970}
1971
1972/*
1973 * Clean up a previously generated link list
1974 *
1975 * We have a separate function, don't assume that the chain can't be reused.
1976 */
5ade6c4d 1977static int tsi148_dma_list_empty(struct vme_dma_list *list)
d22b8ed9
MW
1978{
1979 struct list_head *pos, *temp;
7946328f 1980 struct tsi148_dma_entry *entry;
d22b8ed9 1981
3abc48ae
MW
1982 struct vme_bridge *tsi148_bridge = list->parent->parent;
1983
d22b8ed9 1984 /* detach and free each entry */
886953e9 1985 list_for_each_safe(pos, temp, &list->entries) {
d22b8ed9
MW
1986 list_del(pos);
1987 entry = list_entry(pos, struct tsi148_dma_entry, list);
3abc48ae
MW
1988
1989 dma_unmap_single(tsi148_bridge->parent, entry->dma_handle,
1990 sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
d22b8ed9
MW
1991 kfree(entry);
1992 }
1993
7946328f 1994 return 0;
d22b8ed9
MW
1995}
1996
1997/*
1998 * All 4 location monitors reside at the same base - this is therefore a
1999 * system wide configuration.
2000 *
2001 * This does not enable the LM monitor - that should be done when the first
2002 * callback is attached and disabled when the last callback is removed.
2003 */
5ade6c4d 2004static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
6af04b06 2005 u32 aspace, u32 cycle)
d22b8ed9
MW
2006{
2007 u32 lm_base_high, lm_base_low, lm_ctl = 0;
2008 int i;
48d9356e 2009 struct vme_bridge *tsi148_bridge;
29848ac9
MW
2010 struct tsi148_driver *bridge;
2011
48d9356e
MW
2012 tsi148_bridge = lm->parent;
2013
2014 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2015
886953e9 2016 mutex_lock(&lm->mtx);
d22b8ed9
MW
2017
2018 /* If we already have a callback attached, we can't move it! */
42fb5031 2019 for (i = 0; i < lm->monitors; i++) {
29848ac9 2020 if (bridge->lm_callback[i] != NULL) {
886953e9 2021 mutex_unlock(&lm->mtx);
48d9356e
MW
2022 dev_err(tsi148_bridge->parent, "Location monitor "
2023 "callback attached, can't reset\n");
d22b8ed9
MW
2024 return -EBUSY;
2025 }
2026 }
2027
2028 switch (aspace) {
2029 case VME_A16:
2030 lm_ctl |= TSI148_LCSR_LMAT_AS_A16;
2031 break;
2032 case VME_A24:
2033 lm_ctl |= TSI148_LCSR_LMAT_AS_A24;
2034 break;
2035 case VME_A32:
2036 lm_ctl |= TSI148_LCSR_LMAT_AS_A32;
2037 break;
2038 case VME_A64:
2039 lm_ctl |= TSI148_LCSR_LMAT_AS_A64;
2040 break;
2041 default:
886953e9 2042 mutex_unlock(&lm->mtx);
48d9356e 2043 dev_err(tsi148_bridge->parent, "Invalid address space\n");
d22b8ed9
MW
2044 return -EINVAL;
2045 break;
2046 }
2047
2048 if (cycle & VME_SUPER)
2049 lm_ctl |= TSI148_LCSR_LMAT_SUPR ;
2050 if (cycle & VME_USER)
2051 lm_ctl |= TSI148_LCSR_LMAT_NPRIV;
2052 if (cycle & VME_PROG)
2053 lm_ctl |= TSI148_LCSR_LMAT_PGM;
2054 if (cycle & VME_DATA)
2055 lm_ctl |= TSI148_LCSR_LMAT_DATA;
2056
2057 reg_split(lm_base, &lm_base_high, &lm_base_low);
2058
29848ac9
MW
2059 iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU);
2060 iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL);
2061 iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9 2062
886953e9 2063 mutex_unlock(&lm->mtx);
d22b8ed9
MW
2064
2065 return 0;
2066}
2067
2068/* Get configuration of the callback monitor and return whether it is enabled
2069 * or disabled.
2070 */
5ade6c4d 2071static int tsi148_lm_get(struct vme_lm_resource *lm,
6af04b06 2072 unsigned long long *lm_base, u32 *aspace, u32 *cycle)
d22b8ed9
MW
2073{
2074 u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
29848ac9
MW
2075 struct tsi148_driver *bridge;
2076
2077 bridge = lm->parent->driver_priv;
d22b8ed9 2078
886953e9 2079 mutex_lock(&lm->mtx);
d22b8ed9 2080
29848ac9
MW
2081 lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU);
2082 lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL);
2083 lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2084
2085 reg_join(lm_base_high, lm_base_low, lm_base);
2086
2087 if (lm_ctl & TSI148_LCSR_LMAT_EN)
2088 enabled = 1;
2089
7946328f 2090 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16)
d22b8ed9 2091 *aspace |= VME_A16;
7946328f
MW
2092
2093 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24)
d22b8ed9 2094 *aspace |= VME_A24;
7946328f
MW
2095
2096 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32)
d22b8ed9 2097 *aspace |= VME_A32;
7946328f
MW
2098
2099 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64)
d22b8ed9 2100 *aspace |= VME_A64;
7946328f 2101
d22b8ed9
MW
2102
2103 if (lm_ctl & TSI148_LCSR_LMAT_SUPR)
2104 *cycle |= VME_SUPER;
2105 if (lm_ctl & TSI148_LCSR_LMAT_NPRIV)
2106 *cycle |= VME_USER;
2107 if (lm_ctl & TSI148_LCSR_LMAT_PGM)
2108 *cycle |= VME_PROG;
2109 if (lm_ctl & TSI148_LCSR_LMAT_DATA)
2110 *cycle |= VME_DATA;
2111
886953e9 2112 mutex_unlock(&lm->mtx);
d22b8ed9
MW
2113
2114 return enabled;
2115}
2116
2117/*
2118 * Attach a callback to a specific location monitor.
2119 *
2120 * Callback will be passed the monitor triggered.
2121 */
5ade6c4d 2122static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
42fb5031 2123 void (*callback)(int))
d22b8ed9
MW
2124{
2125 u32 lm_ctl, tmp;
48d9356e 2126 struct vme_bridge *tsi148_bridge;
29848ac9
MW
2127 struct tsi148_driver *bridge;
2128
48d9356e
MW
2129 tsi148_bridge = lm->parent;
2130
2131 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2132
886953e9 2133 mutex_lock(&lm->mtx);
d22b8ed9
MW
2134
2135 /* Ensure that the location monitor is configured - need PGM or DATA */
29848ac9 2136 lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
d22b8ed9 2137 if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
886953e9 2138 mutex_unlock(&lm->mtx);
48d9356e
MW
2139 dev_err(tsi148_bridge->parent, "Location monitor not properly "
2140 "configured\n");
d22b8ed9
MW
2141 return -EINVAL;
2142 }
2143
2144 /* Check that a callback isn't already attached */
29848ac9 2145 if (bridge->lm_callback[monitor] != NULL) {
886953e9 2146 mutex_unlock(&lm->mtx);
48d9356e 2147 dev_err(tsi148_bridge->parent, "Existing callback attached\n");
d22b8ed9
MW
2148 return -EBUSY;
2149 }
2150
2151 /* Attach callback */
29848ac9 2152 bridge->lm_callback[monitor] = callback;
d22b8ed9
MW
2153
2154 /* Enable Location Monitor interrupt */
29848ac9 2155 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2156 tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
29848ac9 2157 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2158
29848ac9 2159 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
d22b8ed9 2160 tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
29848ac9 2161 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
d22b8ed9
MW
2162
2163 /* Ensure that global Location Monitor Enable set */
2164 if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
2165 lm_ctl |= TSI148_LCSR_LMAT_EN;
29848ac9 2166 iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2167 }
2168
886953e9 2169 mutex_unlock(&lm->mtx);
d22b8ed9
MW
2170
2171 return 0;
2172}
2173
2174/*
2175 * Detach a callback function forn a specific location monitor.
2176 */
5ade6c4d 2177static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
d22b8ed9
MW
2178{
2179 u32 lm_en, tmp;
29848ac9
MW
2180 struct tsi148_driver *bridge;
2181
2182 bridge = lm->parent->driver_priv;
d22b8ed9 2183
886953e9 2184 mutex_lock(&lm->mtx);
d22b8ed9
MW
2185
2186 /* Disable Location Monitor and ensure previous interrupts are clear */
29848ac9 2187 lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2188 lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
29848ac9 2189 iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2190
29848ac9 2191 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
d22b8ed9 2192 tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
29848ac9 2193 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
d22b8ed9
MW
2194
2195 iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
29848ac9 2196 bridge->base + TSI148_LCSR_INTC);
d22b8ed9
MW
2197
2198 /* Detach callback */
29848ac9 2199 bridge->lm_callback[monitor] = NULL;
d22b8ed9
MW
2200
2201 /* If all location monitors disabled, disable global Location Monitor */
2202 if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
2203 TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
29848ac9 2204 tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT);
d22b8ed9 2205 tmp &= ~TSI148_LCSR_LMAT_EN;
29848ac9 2206 iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2207 }
2208
886953e9 2209 mutex_unlock(&lm->mtx);
d22b8ed9
MW
2210
2211 return 0;
2212}
2213
2214/*
2215 * Determine Geographical Addressing
2216 */
5ade6c4d 2217static int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
d22b8ed9 2218{
7946328f 2219 u32 slot = 0;
29848ac9
MW
2220 struct tsi148_driver *bridge;
2221
2222 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2223
638f199d 2224 if (!geoid) {
29848ac9 2225 slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT);
638f199d
MW
2226 slot = slot & TSI148_LCSR_VSTAT_GA_M;
2227 } else
2228 slot = geoid;
2229
d22b8ed9
MW
2230 return (int)slot;
2231}
2232
8a508ff4 2233static void *tsi148_alloc_consistent(struct device *parent, size_t size,
7f58f025
MV
2234 dma_addr_t *dma)
2235{
2236 struct pci_dev *pdev;
2237
2238 /* Find pci_dev container of dev */
177581fa 2239 pdev = to_pci_dev(parent);
7f58f025
MV
2240
2241 return pci_alloc_consistent(pdev, size, dma);
2242}
2243
8a508ff4
HS
2244static void tsi148_free_consistent(struct device *parent, size_t size,
2245 void *vaddr, dma_addr_t dma)
7f58f025
MV
2246{
2247 struct pci_dev *pdev;
2248
2249 /* Find pci_dev container of dev */
177581fa 2250 pdev = to_pci_dev(parent);
7f58f025
MV
2251
2252 pci_free_consistent(pdev, size, vaddr, dma);
2253}
2254
d22b8ed9
MW
2255/*
2256 * Configure CR/CSR space
2257 *
2258 * Access to the CR/CSR can be configured at power-up. The location of the
2259 * CR/CSR registers in the CR/CSR address space is determined by the boards
2260 * Auto-ID or Geographic address. This function ensures that the window is
2261 * enabled at an offset consistent with the boards geopgraphic address.
2262 *
2263 * Each board has a 512kB window, with the highest 4kB being used for the
2264 * boards registers, this means there is a fix length 508kB window which must
2265 * be mapped onto PCI memory.
2266 */
29848ac9
MW
2267static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
2268 struct pci_dev *pdev)
d22b8ed9
MW
2269{
2270 u32 cbar, crat, vstat;
2271 u32 crcsr_bus_high, crcsr_bus_low;
2272 int retval;
29848ac9
MW
2273 struct tsi148_driver *bridge;
2274
2275 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
2276
2277 /* Allocate mem for CR/CSR image */
29848ac9 2278 bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
886953e9 2279 &bridge->crcsr_bus);
29848ac9 2280 if (bridge->crcsr_kernel == NULL) {
48d9356e
MW
2281 dev_err(tsi148_bridge->parent, "Failed to allocate memory for "
2282 "CR/CSR image\n");
d22b8ed9
MW
2283 return -ENOMEM;
2284 }
2285
29848ac9 2286 memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
d22b8ed9 2287
29848ac9 2288 reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
d22b8ed9 2289
29848ac9
MW
2290 iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU);
2291 iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL);
d22b8ed9
MW
2292
2293 /* Ensure that the CR/CSR is configured at the correct offset */
29848ac9 2294 cbar = ioread32be(bridge->base + TSI148_CBAR);
d22b8ed9
MW
2295 cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
2296
29848ac9 2297 vstat = tsi148_slot_get(tsi148_bridge);
d22b8ed9
MW
2298
2299 if (cbar != vstat) {
638f199d 2300 cbar = vstat;
48d9356e 2301 dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n");
29848ac9 2302 iowrite32be(cbar<<3, bridge->base + TSI148_CBAR);
d22b8ed9 2303 }
48d9356e 2304 dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar);
d22b8ed9 2305
29848ac9 2306 crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
2981795c
MW
2307 if (crat & TSI148_LCSR_CRAT_EN)
2308 dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n");
2309 else {
48d9356e 2310 dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n");
d22b8ed9 2311 iowrite32be(crat | TSI148_LCSR_CRAT_EN,
29848ac9 2312 bridge->base + TSI148_LCSR_CRAT);
2981795c 2313 }
d22b8ed9
MW
2314
2315 /* If we want flushed, error-checked writes, set up a window
2316 * over the CR/CSR registers. We read from here to safely flush
2317 * through VME writes.
2318 */
7946328f 2319 if (err_chk) {
29848ac9
MW
2320 retval = tsi148_master_set(bridge->flush_image, 1,
2321 (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT,
2322 VME_D16);
d22b8ed9 2323 if (retval)
48d9356e
MW
2324 dev_err(tsi148_bridge->parent, "Configuring flush image"
2325 " failed\n");
d22b8ed9
MW
2326 }
2327
2328 return 0;
2329
2330}
2331
29848ac9
MW
2332static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
2333 struct pci_dev *pdev)
d22b8ed9
MW
2334{
2335 u32 crat;
29848ac9
MW
2336 struct tsi148_driver *bridge;
2337
2338 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
2339
2340 /* Turn off CR/CSR space */
29848ac9 2341 crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
d22b8ed9 2342 iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
29848ac9 2343 bridge->base + TSI148_LCSR_CRAT);
d22b8ed9
MW
2344
2345 /* Free image */
29848ac9
MW
2346 iowrite32be(0, bridge->base + TSI148_LCSR_CROU);
2347 iowrite32be(0, bridge->base + TSI148_LCSR_CROL);
d22b8ed9 2348
29848ac9
MW
2349 pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
2350 bridge->crcsr_bus);
d22b8ed9
MW
2351}
2352
2353static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2354{
2355 int retval, i, master_num;
2356 u32 data;
b49c32ba 2357 struct list_head *pos = NULL, *n;
29848ac9
MW
2358 struct vme_bridge *tsi148_bridge;
2359 struct tsi148_driver *tsi148_device;
d22b8ed9
MW
2360 struct vme_master_resource *master_image;
2361 struct vme_slave_resource *slave_image;
2362 struct vme_dma_resource *dma_ctrlr;
42fb5031 2363 struct vme_lm_resource *lm;
d22b8ed9
MW
2364
2365 /* If we want to support more than one of each bridge, we need to
2366 * dynamically generate this so we get one per device
2367 */
7a6cb0d5 2368 tsi148_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL);
d22b8ed9
MW
2369 if (tsi148_bridge == NULL) {
2370 dev_err(&pdev->dev, "Failed to allocate memory for device "
2371 "structure\n");
2372 retval = -ENOMEM;
2373 goto err_struct;
2374 }
2375
7a6cb0d5 2376 tsi148_device = kzalloc(sizeof(struct tsi148_driver), GFP_KERNEL);
29848ac9
MW
2377 if (tsi148_device == NULL) {
2378 dev_err(&pdev->dev, "Failed to allocate memory for device "
2379 "structure\n");
2380 retval = -ENOMEM;
2381 goto err_driver;
2382 }
2383
29848ac9
MW
2384 tsi148_bridge->driver_priv = tsi148_device;
2385
d22b8ed9
MW
2386 /* Enable the device */
2387 retval = pci_enable_device(pdev);
2388 if (retval) {
2389 dev_err(&pdev->dev, "Unable to enable device\n");
2390 goto err_enable;
2391 }
2392
2393 /* Map Registers */
2394 retval = pci_request_regions(pdev, driver_name);
2395 if (retval) {
2396 dev_err(&pdev->dev, "Unable to reserve resources\n");
2397 goto err_resource;
2398 }
2399
2400 /* map registers in BAR 0 */
29848ac9
MW
2401 tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
2402 4096);
2403 if (!tsi148_device->base) {
d22b8ed9
MW
2404 dev_err(&pdev->dev, "Unable to remap CRG region\n");
2405 retval = -EIO;
2406 goto err_remap;
2407 }
2408
2409 /* Check to see if the mapping worked out */
29848ac9 2410 data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF;
d22b8ed9
MW
2411 if (data != PCI_VENDOR_ID_TUNDRA) {
2412 dev_err(&pdev->dev, "CRG region check failed\n");
2413 retval = -EIO;
2414 goto err_test;
2415 }
2416
2417 /* Initialize wait queues & mutual exclusion flags */
886953e9
EC
2418 init_waitqueue_head(&tsi148_device->dma_queue[0]);
2419 init_waitqueue_head(&tsi148_device->dma_queue[1]);
2420 init_waitqueue_head(&tsi148_device->iack_queue);
2421 mutex_init(&tsi148_device->vme_int);
2422 mutex_init(&tsi148_device->vme_rmw);
d22b8ed9 2423
886953e9 2424 tsi148_bridge->parent = &pdev->dev;
d22b8ed9
MW
2425 strcpy(tsi148_bridge->name, driver_name);
2426
2427 /* Setup IRQ */
2428 retval = tsi148_irq_init(tsi148_bridge);
2429 if (retval != 0) {
2430 dev_err(&pdev->dev, "Chip Initialization failed.\n");
2431 goto err_irq;
2432 }
2433
2434 /* If we are going to flush writes, we need to read from the VME bus.
2435 * We need to do this safely, thus we read the devices own CR/CSR
2436 * register. To do this we must set up a window in CR/CSR space and
2437 * hence have one less master window resource available.
2438 */
2439 master_num = TSI148_MAX_MASTER;
7946328f 2440 if (err_chk) {
d22b8ed9 2441 master_num--;
29848ac9 2442
32414878 2443 tsi148_device->flush_image =
29848ac9
MW
2444 kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL);
2445 if (tsi148_device->flush_image == NULL) {
d22b8ed9
MW
2446 dev_err(&pdev->dev, "Failed to allocate memory for "
2447 "flush resource structure\n");
2448 retval = -ENOMEM;
2449 goto err_master;
2450 }
29848ac9 2451 tsi148_device->flush_image->parent = tsi148_bridge;
886953e9 2452 spin_lock_init(&tsi148_device->flush_image->lock);
29848ac9
MW
2453 tsi148_device->flush_image->locked = 1;
2454 tsi148_device->flush_image->number = master_num;
886953e9 2455 memset(&tsi148_device->flush_image->bus_resource, 0,
d22b8ed9 2456 sizeof(struct resource));
29848ac9 2457 tsi148_device->flush_image->kern_base = NULL;
d22b8ed9
MW
2458 }
2459
2460 /* Add master windows to list */
886953e9 2461 INIT_LIST_HEAD(&tsi148_bridge->master_resources);
d22b8ed9 2462 for (i = 0; i < master_num; i++) {
7946328f
MW
2463 master_image = kmalloc(sizeof(struct vme_master_resource),
2464 GFP_KERNEL);
d22b8ed9
MW
2465 if (master_image == NULL) {
2466 dev_err(&pdev->dev, "Failed to allocate memory for "
2467 "master resource structure\n");
2468 retval = -ENOMEM;
2469 goto err_master;
2470 }
2471 master_image->parent = tsi148_bridge;
886953e9 2472 spin_lock_init(&master_image->lock);
d22b8ed9
MW
2473 master_image->locked = 0;
2474 master_image->number = i;
2475 master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
2476 VME_A64;
2477 master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
2478 VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
2479 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
2480 VME_PROG | VME_DATA;
2481 master_image->width_attr = VME_D16 | VME_D32;
886953e9 2482 memset(&master_image->bus_resource, 0,
d22b8ed9
MW
2483 sizeof(struct resource));
2484 master_image->kern_base = NULL;
886953e9
EC
2485 list_add_tail(&master_image->list,
2486 &tsi148_bridge->master_resources);
d22b8ed9
MW
2487 }
2488
2489 /* Add slave windows to list */
886953e9 2490 INIT_LIST_HEAD(&tsi148_bridge->slave_resources);
d22b8ed9 2491 for (i = 0; i < TSI148_MAX_SLAVE; i++) {
7946328f
MW
2492 slave_image = kmalloc(sizeof(struct vme_slave_resource),
2493 GFP_KERNEL);
d22b8ed9
MW
2494 if (slave_image == NULL) {
2495 dev_err(&pdev->dev, "Failed to allocate memory for "
2496 "slave resource structure\n");
2497 retval = -ENOMEM;
2498 goto err_slave;
2499 }
2500 slave_image->parent = tsi148_bridge;
886953e9 2501 mutex_init(&slave_image->mtx);
d22b8ed9
MW
2502 slave_image->locked = 0;
2503 slave_image->number = i;
2504 slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
2505 VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
2506 VME_USER3 | VME_USER4;
2507 slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
2508 VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
2509 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
2510 VME_PROG | VME_DATA;
886953e9
EC
2511 list_add_tail(&slave_image->list,
2512 &tsi148_bridge->slave_resources);
d22b8ed9
MW
2513 }
2514
2515 /* Add dma engines to list */
886953e9 2516 INIT_LIST_HEAD(&tsi148_bridge->dma_resources);
d22b8ed9 2517 for (i = 0; i < TSI148_MAX_DMA; i++) {
7946328f
MW
2518 dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource),
2519 GFP_KERNEL);
d22b8ed9
MW
2520 if (dma_ctrlr == NULL) {
2521 dev_err(&pdev->dev, "Failed to allocate memory for "
2522 "dma resource structure\n");
2523 retval = -ENOMEM;
2524 goto err_dma;
2525 }
2526 dma_ctrlr->parent = tsi148_bridge;
886953e9 2527 mutex_init(&dma_ctrlr->mtx);
d22b8ed9
MW
2528 dma_ctrlr->locked = 0;
2529 dma_ctrlr->number = i;
4f723df4
MW
2530 dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
2531 VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
2532 VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
2533 VME_DMA_PATTERN_TO_MEM;
886953e9
EC
2534 INIT_LIST_HEAD(&dma_ctrlr->pending);
2535 INIT_LIST_HEAD(&dma_ctrlr->running);
2536 list_add_tail(&dma_ctrlr->list,
2537 &tsi148_bridge->dma_resources);
d22b8ed9
MW
2538 }
2539
42fb5031 2540 /* Add location monitor to list */
886953e9 2541 INIT_LIST_HEAD(&tsi148_bridge->lm_resources);
42fb5031
MW
2542 lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
2543 if (lm == NULL) {
2544 dev_err(&pdev->dev, "Failed to allocate memory for "
2545 "location monitor resource structure\n");
2546 retval = -ENOMEM;
2547 goto err_lm;
2548 }
2549 lm->parent = tsi148_bridge;
886953e9 2550 mutex_init(&lm->mtx);
42fb5031
MW
2551 lm->locked = 0;
2552 lm->number = 1;
2553 lm->monitors = 4;
886953e9 2554 list_add_tail(&lm->list, &tsi148_bridge->lm_resources);
42fb5031 2555
d22b8ed9
MW
2556 tsi148_bridge->slave_get = tsi148_slave_get;
2557 tsi148_bridge->slave_set = tsi148_slave_set;
2558 tsi148_bridge->master_get = tsi148_master_get;
2559 tsi148_bridge->master_set = tsi148_master_set;
2560 tsi148_bridge->master_read = tsi148_master_read;
2561 tsi148_bridge->master_write = tsi148_master_write;
2562 tsi148_bridge->master_rmw = tsi148_master_rmw;
2563 tsi148_bridge->dma_list_add = tsi148_dma_list_add;
2564 tsi148_bridge->dma_list_exec = tsi148_dma_list_exec;
2565 tsi148_bridge->dma_list_empty = tsi148_dma_list_empty;
c813f592
MW
2566 tsi148_bridge->irq_set = tsi148_irq_set;
2567 tsi148_bridge->irq_generate = tsi148_irq_generate;
d22b8ed9
MW
2568 tsi148_bridge->lm_set = tsi148_lm_set;
2569 tsi148_bridge->lm_get = tsi148_lm_get;
2570 tsi148_bridge->lm_attach = tsi148_lm_attach;
2571 tsi148_bridge->lm_detach = tsi148_lm_detach;
2572 tsi148_bridge->slot_get = tsi148_slot_get;
7f58f025
MV
2573 tsi148_bridge->alloc_consistent = tsi148_alloc_consistent;
2574 tsi148_bridge->free_consistent = tsi148_free_consistent;
d22b8ed9 2575
29848ac9 2576 data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
d22b8ed9 2577 dev_info(&pdev->dev, "Board is%s the VME system controller\n",
7946328f 2578 (data & TSI148_LCSR_VSTAT_SCONS) ? "" : " not");
29848ac9 2579 if (!geoid)
638f199d
MW
2580 dev_info(&pdev->dev, "VME geographical address is %d\n",
2581 data & TSI148_LCSR_VSTAT_GA_M);
29848ac9 2582 else
638f199d
MW
2583 dev_info(&pdev->dev, "VME geographical address is set to %d\n",
2584 geoid);
29848ac9 2585
d22b8ed9
MW
2586 dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
2587 err_chk ? "enabled" : "disabled");
2588
0686ab7a
WY
2589 retval = tsi148_crcsr_init(tsi148_bridge, pdev);
2590 if (retval) {
d22b8ed9
MW
2591 dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
2592 goto err_crcsr;
4839737b 2593 }
d22b8ed9 2594
d22b8ed9
MW
2595 retval = vme_register_bridge(tsi148_bridge);
2596 if (retval != 0) {
2597 dev_err(&pdev->dev, "Chip Registration failed.\n");
2598 goto err_reg;
2599 }
2600
29848ac9
MW
2601 pci_set_drvdata(pdev, tsi148_bridge);
2602
d22b8ed9 2603 /* Clear VME bus "board fail", and "power-up reset" lines */
29848ac9 2604 data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
d22b8ed9
MW
2605 data &= ~TSI148_LCSR_VSTAT_BRDFL;
2606 data |= TSI148_LCSR_VSTAT_CPURST;
29848ac9 2607 iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT);
d22b8ed9
MW
2608
2609 return 0;
2610
d22b8ed9 2611err_reg:
29848ac9 2612 tsi148_crcsr_exit(tsi148_bridge, pdev);
d22b8ed9 2613err_crcsr:
42fb5031
MW
2614err_lm:
2615 /* resources are stored in link list */
b49c32ba 2616 list_for_each_safe(pos, n, &tsi148_bridge->lm_resources) {
42fb5031
MW
2617 lm = list_entry(pos, struct vme_lm_resource, list);
2618 list_del(pos);
2619 kfree(lm);
2620 }
d22b8ed9
MW
2621err_dma:
2622 /* resources are stored in link list */
b49c32ba 2623 list_for_each_safe(pos, n, &tsi148_bridge->dma_resources) {
d22b8ed9
MW
2624 dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
2625 list_del(pos);
2626 kfree(dma_ctrlr);
2627 }
2628err_slave:
2629 /* resources are stored in link list */
b49c32ba 2630 list_for_each_safe(pos, n, &tsi148_bridge->slave_resources) {
d22b8ed9
MW
2631 slave_image = list_entry(pos, struct vme_slave_resource, list);
2632 list_del(pos);
2633 kfree(slave_image);
2634 }
2635err_master:
2636 /* resources are stored in link list */
b49c32ba 2637 list_for_each_safe(pos, n, &tsi148_bridge->master_resources) {
7946328f
MW
2638 master_image = list_entry(pos, struct vme_master_resource,
2639 list);
d22b8ed9
MW
2640 list_del(pos);
2641 kfree(master_image);
2642 }
2643
a82ad05e 2644 tsi148_irq_exit(tsi148_bridge, pdev);
d22b8ed9
MW
2645err_irq:
2646err_test:
29848ac9 2647 iounmap(tsi148_device->base);
d22b8ed9
MW
2648err_remap:
2649 pci_release_regions(pdev);
2650err_resource:
2651 pci_disable_device(pdev);
2652err_enable:
29848ac9
MW
2653 kfree(tsi148_device);
2654err_driver:
d22b8ed9
MW
2655 kfree(tsi148_bridge);
2656err_struct:
2657 return retval;
2658
2659}
2660
2661static void tsi148_remove(struct pci_dev *pdev)
2662{
2663 struct list_head *pos = NULL;
b558ba2f 2664 struct list_head *tmplist;
d22b8ed9
MW
2665 struct vme_master_resource *master_image;
2666 struct vme_slave_resource *slave_image;
2667 struct vme_dma_resource *dma_ctrlr;
2668 int i;
29848ac9
MW
2669 struct tsi148_driver *bridge;
2670 struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev);
2671
2672 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2673
d22b8ed9 2674
29848ac9 2675 dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
d22b8ed9
MW
2676
2677 /*
2678 * Shutdown all inbound and outbound windows.
2679 */
2680 for (i = 0; i < 8; i++) {
29848ac9 2681 iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 2682 TSI148_LCSR_OFFSET_ITAT);
29848ac9 2683 iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
2684 TSI148_LCSR_OFFSET_OTAT);
2685 }
2686
2687 /*
2688 * Shutdown Location monitor.
2689 */
29848ac9 2690 iowrite32be(0, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2691
2692 /*
2693 * Shutdown CRG map.
2694 */
29848ac9 2695 iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT);
d22b8ed9
MW
2696
2697 /*
2698 * Clear error status.
2699 */
29848ac9
MW
2700 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT);
2701 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT);
2702 iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT);
d22b8ed9
MW
2703
2704 /*
2705 * Remove VIRQ interrupt (if any)
2706 */
29848ac9
MW
2707 if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800)
2708 iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR);
d22b8ed9 2709
d22b8ed9
MW
2710 /*
2711 * Map all Interrupts to PCI INTA
2712 */
29848ac9
MW
2713 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1);
2714 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2);
d22b8ed9 2715
a82ad05e 2716 tsi148_irq_exit(tsi148_bridge, pdev);
d22b8ed9
MW
2717
2718 vme_unregister_bridge(tsi148_bridge);
2719
29848ac9 2720 tsi148_crcsr_exit(tsi148_bridge, pdev);
d22b8ed9
MW
2721
2722 /* resources are stored in link list */
b558ba2f 2723 list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) {
d22b8ed9
MW
2724 dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
2725 list_del(pos);
2726 kfree(dma_ctrlr);
2727 }
2728
2729 /* resources are stored in link list */
b558ba2f 2730 list_for_each_safe(pos, tmplist, &tsi148_bridge->slave_resources) {
d22b8ed9
MW
2731 slave_image = list_entry(pos, struct vme_slave_resource, list);
2732 list_del(pos);
2733 kfree(slave_image);
2734 }
2735
2736 /* resources are stored in link list */
b558ba2f 2737 list_for_each_safe(pos, tmplist, &tsi148_bridge->master_resources) {
638f199d
MW
2738 master_image = list_entry(pos, struct vme_master_resource,
2739 list);
d22b8ed9
MW
2740 list_del(pos);
2741 kfree(master_image);
2742 }
2743
29848ac9 2744 iounmap(bridge->base);
d22b8ed9
MW
2745
2746 pci_release_regions(pdev);
2747
2748 pci_disable_device(pdev);
2749
29848ac9
MW
2750 kfree(tsi148_bridge->driver_priv);
2751
d22b8ed9
MW
2752 kfree(tsi148_bridge);
2753}
2754
01c07143 2755module_pci_driver(tsi148_driver);
d22b8ed9
MW
2756
2757MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
2758module_param(err_chk, bool, 0);
2759
638f199d
MW
2760MODULE_PARM_DESC(geoid, "Override geographical addressing");
2761module_param(geoid, int, 0);
2762
d22b8ed9
MW
2763MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
2764MODULE_LICENSE("GPL");
This page took 0.673588 seconds and 5 git commands to generate.