OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [m8xx_pcmcia.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
3
 *
4
 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
5
 * (C) 2001-2002 Montavista Software, Inc.
6
 *     <mlocke@mvista.com>
7
 *
8
 * "The ExCA standard specifies that socket controllers should provide
9
 * two IO and five memory windows per socket, which can be independently
10
 * configured and positioned in the host address space and mapped to
11
 * arbitrary segments of card address space. " - David A Hinds. 1999
12
 *
13
 * This controller does _not_ meet the ExCA standard.
14
 *
15
 * m8xx pcmcia controller brief info:
16
 * + 8 windows (attrib, mem, i/o)
17
 * + up to two slots (SLOT_A and SLOT_B)
18
 * + inputpins, outputpins, event and mask registers.
19
 * - no offset register. sigh.
20
 *
21
 * Because of the lacking offset register we must map the whole card.
22
 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
23
 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
24
 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
25
 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
26
 * They are maximum 64KByte each...
27
 */
28
 
29
#include <linux/module.h>
30
#include <linux/init.h>
31
#include <linux/types.h>
32
#include <linux/fcntl.h>
33
#include <linux/string.h>
34
 
35
#include <asm/io.h>
36
#include <asm/bitops.h>
37
#include <asm/segment.h>
38
#include <asm/system.h>
39
 
40
#include <linux/kernel.h>
41
#include <linux/errno.h>
42
#include <linux/sched.h>
43
#include <linux/slab.h>
44
#include <linux/timer.h>
45
#include <linux/ioport.h>
46
#include <linux/delay.h>
47
 
48
#include <asm/mpc8xx.h>
49
#include <asm/8xx_immap.h>
50
#include <asm/irq.h>
51
 
52
#include <pcmcia/version.h>
53
#include <pcmcia/cs_types.h>
54
#include <pcmcia/cs.h>
55
#include <pcmcia/ss.h>
56
 
57
#ifdef PCMCIA_DEBUG
58
static int pc_debug = PCMCIA_DEBUG;
59
MODULE_PARM(pc_debug, "i");
60
#define DEBUG(n, args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
61
#else
62
#define DEBUG(n, args...)
63
#endif
64
 
65
#define PCMCIA_INFO(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
66
#define PCMCIA_ERROR(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
67
 
68
static const char *version = "Version 0.05, 14-Apr-2002";
69
MODULE_LICENSE("Dual MPL/GPL");
70
 
71
/* The RPX series use SLOT_B */
72
 
73
#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
74
#define CONFIG_PCMCIA_SLOT_B
75
#endif
76
 
77
/* The MBX board use SLOT_A */
78
 
79
#ifdef CONFIG_MBX
80
#define CONFIG_PCMCIA_SLOT_A
81
#endif
82
 
83
/* The FADS860T board use SLOT_A */
84
 
85
#ifdef CONFIG_FADS
86
#define CONFIG_PCMCIA_SLOT_A
87
#endif
88
 
89
/* ------------------------------------------------------------------------- */
90
 
91
#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0   */
92
#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte     */
93
#define PCMCIA_IO_WIN_BASE  _IO_BASE   /* base address for io window 0       */
94
 
95
#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level      */
96
 
97
/* ------------------------------------------------------------------------- */
98
 
99
#define PCMCIA_SOCKETS_NO 1
100
 
101
#define PCMCIA_MEM_WIN_NO 5
102
#define PCMCIA_IO_WIN_NO  2
103
 
104
/* define _slot_ to be able to optimize macros */
105
 
106
#ifdef CONFIG_PCMCIA_SLOT_A
107
#define _slot_ 0
108
#define PCMCIA_SLOT_MSG "SLOT_A"
109
#else
110
#define _slot_ 1
111
#define PCMCIA_SLOT_MSG "SLOT_B"
112
#endif
113
 
114
#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
115
 
116
static int pcmcia_schlvl = PCMCIA_SCHLVL;
117
 
118
/* ------------------------------------------------------------------------- */
119
 
120
#define PCMCIA_SOCKET_KEY_5V 1
121
#define PCMCIA_SOCKET_KEY_LV 2
122
 
123
 
124
/* look up table for pgcrx registers */
125
 
126
static u_int *m8xx_pgcrx[2] = {
127
        &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
128
        &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
129
};
130
 
131
/*
132
 * This structure is used to address each window in the PCMCIA controller.
133
 *
134
 * Keep in mind that we assume that pcmcia_win_t[n+1] is mapped directly
135
 * after pcmcia_win_t[n]...
136
 */
137
 
138
typedef struct {
139
        uint    br;
140
        uint    or;
141
} pcmcia_win_t;
142
 
143
/*
144
 * For some reason the hardware guys decided to make both slots share
145
 * some registers.
146
 *
147
 * Could someone invent object oriented hardware ?
148
 *
149
 * The macros are used to get the right bit from the registers.
150
 * SLOT_A : slot = 0
151
 * SLOT_B : slot = 1
152
 */
153
 
154
#define M8XX_PCMCIA_VS1(slot)      (0x80000000 >> (slot << 4))
155
#define M8XX_PCMCIA_VS2(slot)      (0x40000000 >> (slot << 4))
156
#define M8XX_PCMCIA_VS_MASK(slot)  (0xc0000000 >> (slot << 4))
157
#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
158
 
159
#define M8XX_PCMCIA_WP(slot)       (0x20000000 >> (slot << 4))
160
#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
161
#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
162
#define M8XX_PCMCIA_BVD2(slot)     (0x04000000 >> (slot << 4))
163
#define M8XX_PCMCIA_BVD1(slot)     (0x02000000 >> (slot << 4))
164
#define M8XX_PCMCIA_RDY(slot)      (0x01000000 >> (slot << 4))
165
#define M8XX_PCMCIA_RDY_L(slot)    (0x00800000 >> (slot << 4))
166
#define M8XX_PCMCIA_RDY_H(slot)    (0x00400000 >> (slot << 4))
167
#define M8XX_PCMCIA_RDY_R(slot)    (0x00200000 >> (slot << 4))
168
#define M8XX_PCMCIA_RDY_F(slot)    (0x00100000 >> (slot << 4))
169
#define M8XX_PCMCIA_MASK(slot)     (0xFFFF0000 >> (slot << 4))
170
 
171
#define M8XX_PGCRX(slot)  (*m8xx_pgcrx[slot])
172
 
173
#define M8XX_PGCRX_CXOE    0x00000080
174
#define M8XX_PGCRX_CXRESET 0x00000040
175
 
176
/* we keep one lookup table per socket to check flags */
177
 
178
#define PCMCIA_EVENTS_MAX 5  /* 4 max at a time + termination */
179
 
180
typedef struct  {
181
        u_int regbit;
182
        u_int eventbit;
183
} event_table_t;
184
 
185
typedef struct socket_info_t {
186
    void        (*handler)(void *info, u_int events);
187
    void        *info;
188
 
189
    u_int  slot;
190
 
191
    socket_state_t state;
192
    struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
193
    struct pccard_io_map  io_win[PCMCIA_IO_WIN_NO];
194
    event_table_t events[PCMCIA_EVENTS_MAX];
195
} socket_info_t;
196
 
197
static socket_info_t socket[PCMCIA_SOCKETS_NO];
198
 
199
static socket_cap_t capabilities = {
200
    SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP, /* features -
201
                                                             only 16-bit cards,
202
                                                             memory windows must be
203
                                                             size-aligned */
204
    0x000,              /* irq_mask - SIU_LEVEL 7 -> 0          */
205
    0x1000,             /* map_size - 4K minimum window size    */
206
    0,                   /* io_offset -                  */
207
    9,                  /* pci_irq */
208
 
209
};
210
 
211
/*
212
 * Search this table to see if the windowsize is
213
 * supported...
214
 */
215
 
216
#define M8XX_SIZES_NO 32
217
 
218
static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
219
{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
220
  0x00000080, 0x00000040, 0x00000010, 0x00000020,
221
  0x00008000, 0x00004000, 0x00001000, 0x00002000,
222
  0x00000100, 0x00000200, 0x00000800, 0x00000400,
223
 
224
  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
225
  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
226
  0x00010000, 0x00020000, 0x00080000, 0x00040000,
227
  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
228
 
229
 
230
/* ------------------------------------------------------------------------- */
231
 
232
static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
233
 
234
#define PCMCIA_BMT_LIMIT (15*4)  /* Bus Monitor Timeout value */
235
 
236
/* ------------------------------------------------------------------------- */
237
/* board specific stuff:                                                     */
238
/* voltage_set(), hardware_enable() and hardware_disable()                   */
239
/* ------------------------------------------------------------------------- */
240
/* RPX Boards from Embedded Planet                                           */
241
 
242
#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
243
 
244
/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
245
 * SYPCR is write once only, therefore must the slowest memory be faster
246
 * than the bus monitor or we will get a machine check due to the bus timeout.
247
 */
248
 
249
#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
250
 
251
#undef PCMCIA_BMT_LIMIT
252
#define PCMCIA_BMT_LIMIT (6*8) 
253
 
254
static int voltage_set(int slot, int vcc, int vpp)
255
{
256
        u_int reg = 0;
257
 
258
        switch(vcc) {
259
        case 0: break;
260
        case 33: reg |= BCSR1_PCVCTL4; break;
261
        case 50: reg |= BCSR1_PCVCTL5; break;
262
        default: return 1;
263
        }
264
 
265
        switch(vpp) {
266
        case 0: break;
267
        case 33:
268
        case 50:
269
                if(vcc == vpp)
270
                        reg |= BCSR1_PCVCTL6;
271
                else
272
                        return 1;
273
                break;
274
        case 120:
275
                reg |= BCSR1_PCVCTL7;
276
        default: return 1;
277
        }
278
 
279
        if(!((vcc == 50) || (vcc == 0)))
280
           return 1;
281
 
282
        /* first, turn off all power */
283
 
284
        *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
285
                                     | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
286
 
287
        /* enable new powersettings */
288
 
289
        *((uint *)RPX_CSR_ADDR) |= reg;
290
 
291
        return 0;
292
}
293
 
294
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
295
#define hardware_enable(_slot_)  /* No hardware to enable */
296
#define hardware_disable(_slot_) /* No hardware to disable */
297
 
298
#endif /* CONFIG_RPXCLASSIC */
299
 
300
/* ------------------------------------------------------------------------- */
301
/* FADS Boards from Motorola                                               */
302
 
303
#if defined(CONFIG_FADS)
304
 
305
#define PCMCIA_BOARD_MSG "FADS"
306
 
307
static int voltage_set(int slot, int vcc, int vpp)
308
{
309
        uint reg = 0;
310
 
311
        switch(vcc) {
312
                case 0: break;
313
                case 33: reg |= BCSR1_PCCVCC0; break;
314
                case 50: reg |= BCSR1_PCCVCC1; break;
315
                default: return 1;
316
        }
317
 
318
        switch(vpp) {
319
                case 0: break;
320
                case 33:
321
                case 50:
322
                        if(vcc == vpp)
323
                                reg |= BCSR1_PCCVPP1;
324
                        else
325
                                return 1;
326
                        break;
327
                case 120:
328
                        if ((vcc == 33) || (vcc == 50))
329
                                reg |= BCSR1_PCCVPP0;
330
                        else
331
                                return 1;
332
                default: return 1;
333
        }
334
 
335
        /* first, turn off all power */
336
        *((uint *)BCSR1) &= ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK);
337
 
338
        /* enable new powersettings */
339
        *((uint *)BCSR1) |= reg;
340
 
341
        return 0;
342
}
343
 
344
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
345
 
346
static void hardware_enable(int slot)
347
{
348
        *((uint *)BCSR1) &= ~BCSR1_PCCEN;
349
}
350
 
351
static void hardware_disable(int slot)
352
{
353
        *((uint *)BCSR1) |=  BCSR1_PCCEN;
354
}
355
 
356
#endif
357
 
358
/* ------------------------------------------------------------------------- */
359
/* Motorola MBX860                                                           */
360
 
361
#if defined(CONFIG_MBX)
362
 
363
#define PCMCIA_BOARD_MSG "MBX"
364
 
365
static int voltage_set(int slot, int vcc, int vpp)
366
{
367
        unsigned char reg = 0;
368
 
369
        switch(vcc) {
370
                case 0: break;
371
                case 33: reg |= CSR2_VCC_33; break;
372
                case 50: reg |= CSR2_VCC_50; break;
373
                default: return 1;
374
        }
375
 
376
        switch(vpp) {
377
                case 0: break;
378
                case 33:
379
                case 50:
380
                        if(vcc == vpp)
381
                                reg |= CSR2_VPP_VCC;
382
                        else
383
                                return 1;
384
                        break;
385
                case 120:
386
                        if ((vcc == 33) || (vcc == 50))
387
                                reg |= CSR2_VPP_12;
388
                        else
389
                                return 1;
390
                default: return 1;
391
        }
392
 
393
        /* first, turn off all power */
394
        *((unsigned char *)MBX_CSR2_ADDR) &= ~(CSR2_VCC_MASK | CSR2_VPP_MASK);
395
 
396
        /* enable new powersettings */
397
        *((unsigned char *)MBX_CSR2_ADDR) |= reg;
398
 
399
        return 0;
400
}
401
 
402
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
403
#define hardware_enable(_slot_)  /* No hardware to enable */
404
#define hardware_disable(_slot_) /* No hardware to disable */
405
 
406
#endif /* CONFIG_MBX */
407
 
408
/* ------------------------------------------------------------------------- */
409
 
410
static void m8xx_shutdown(void)
411
{
412
        u_int m;
413
        pcmcia_win_t *w;
414
 
415
 
416
        w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
417
 
418
 
419
                ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr =
420
                        M8XX_PCMCIA_MASK(_slot_);
421
                ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
422
                        &= ~M8XX_PCMCIA_MASK(_slot_);
423
 
424
                /* turn off interrupt and disable CxOE */
425
 
426
                M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE;
427
 
428
                /* turn off memory windows */
429
 
430
                for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
431
                        w->or = 0;  /* set to not valid */
432
                        w++;
433
                }
434
 
435
                /* turn off voltage */
436
 
437
                voltage_set(_slot_, 0, 0);
438
 
439
                /* disable external hardware */
440
 
441
                hardware_disable(_slot_);
442
 
443
        free_irq(pcmcia_schlvl, NULL);
444
 
445
}
446
 
447
/* ------------------------------------------------------------------------- */
448
 
449
/* ------------------------------------------------------------------------- */
450
 
451
static u_int pending_events[PCMCIA_SOCKETS_NO];
452
static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
453
 
454
static void m8xx_pcmcia_bh(void *dummy)
455
{
456
        u_int events;
457
        int i;
458
 
459
        for (i=0; i < PCMCIA_SOCKETS_NO; i++) {
460
                spin_lock_irq(&pending_event_lock);
461
                events = pending_events[i];
462
                pending_events[i] = 0;
463
                spin_unlock_irq(&pending_event_lock);
464
                /*
465
                SS_DETECT events need a small delay here. The reason for this is that
466
                the "is there a card" electronics need time to see the card after the
467
                "we have a card coming in" electronics have seen it.
468
                */
469
                if (events & SS_DETECT)
470
                        mdelay(4);
471
                if (socket[i].handler)
472
                        socket[i].handler(socket[i].info, events);
473
        }
474
}
475
 
476
static struct tq_struct m8xx_pcmcia_task = {
477
        routine:        m8xx_pcmcia_bh
478
};
479
 
480
 
481
static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
482
{
483
        socket_info_t *s;
484
        event_table_t *e;
485
        u_int events, pscr, pipr;
486
 
487
        DEBUG(3,"Interrupt!\n");
488
 
489
        /* get interrupt sources */
490
 
491
        pscr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
492
        pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
493
 
494
        s = &socket[0];
495
 
496
            if(s->handler) {
497
 
498
                    e = &s->events[0];
499
                    events = 0;
500
 
501
                    while(e->regbit) {
502
                            if(pscr & e->regbit)
503
                                    events |= e->eventbit;
504
 
505
                            e++;
506
                    }
507
 
508
                    /*
509
                     * report only if both card detect signals are the same
510
                     * not too nice done,
511
                     * we depend on that CD2 is the bit to the left of CD1...
512
                     */
513
 
514
                    if(events & SS_DETECT)
515
                            if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1)
516
                                    ^ (pipr & M8XX_PCMCIA_CD1(_slot_)))
517
                                    events &= ~SS_DETECT;
518
 
519
#ifdef PCMCIA_GLITCHY_CD
520
 
521
                    /*
522
                     * I've experienced CD problems with my ADS board.
523
                     * We make an extra check to see if there was a
524
                     * real change of Card detection.
525
                     */
526
 
527
                    if((events & SS_DETECT) &&
528
                       ((pipr &
529
                         (M8XX_PCMCIA_CD2(_slot_) | M8XX_PCMCIA_CD1(_slot_)))
530
                        == 0) && (s->state.Vcc | s->state.Vpp)) {
531
                          events &= ~SS_DETECT;
532
                          printk( "CD glitch workaround - CD = 0x%08x!\n",
533
                                (pipr & (M8XX_PCMCIA_CD2(_slot_)
534
                                         | M8XX_PCMCIA_CD1(_slot_))));
535
                    }
536
#endif
537
 
538
                    /* call the handler */
539
 
540
                    DEBUG(3,"slot %u: events = 0x%02x, pscr = 0x%08x, "
541
                          "pipr = 0x%08x\n",
542
                          _slot_, events, pscr, pipr);
543
 
544
                    if(events) {
545
                            spin_lock(&pending_event_lock);
546
                            pending_events[0] |= events;
547
                            spin_unlock(&pending_event_lock);
548
                            schedule_task(&m8xx_pcmcia_task);
549
                    }
550
 
551
            }
552
 
553
 
554
    /* clear the interrupt sources */
555
 
556
    ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
557
 
558
    DEBUG(3,"Interrupt done.\n");
559
 
560
}
561
 
562
/* ------------------------------------------------------------------------- */
563
 
564
static u_int m8xx_get_graycode(u_int size)
565
{
566
        u_int k;
567
 
568
        for(k = 0; k < M8XX_SIZES_NO; k++)
569
                if(m8xx_size_to_gray[k] == size)
570
                        break;
571
 
572
        if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
573
                k = -1;
574
 
575
        return k;
576
}
577
 
578
/* ------------------------------------------------------------------------- */
579
 
580
static u_int m8xx_get_speed(u_int ns, u_int is_io)
581
{
582
        u_int reg, clocks, psst, psl, psht;
583
 
584
        if(!ns) {
585
 
586
                /*
587
                 * We get called with IO maps setup to 0ns
588
                 * if not specified by the user.
589
                 * They should be 255ns.
590
                 */
591
 
592
                if(is_io)
593
                        ns = 255;
594
                else
595
                        ns = 100;  /* fast memory if 0 */
596
        }
597
 
598
        /*
599
         * In PSST, PSL, PSHT fields we tell the controller
600
         * timing parameters in CLKOUT clock cycles.
601
         * CLKOUT is the same as GCLK2_50.
602
         */
603
 
604
/* how we want to adjust the timing - in percent */
605
 
606
#define ADJ 180 /* 80 % longer accesstime - to be sure */
607
 
608
 
609
        clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
610
        clocks = (clocks * ADJ) / (100*1000);
611
        if(clocks >= PCMCIA_BMT_LIMIT) {
612
                printk( "Max access time limit reached\n");
613
                clocks = PCMCIA_BMT_LIMIT-1;
614
        }
615
 
616
        psst = clocks / 7;          /* setup time */
617
        psht = clocks / 7;          /* hold time */
618
        psl  = (clocks * 5) / 7;    /* strobe length */
619
 
620
        psst += clocks - (psst + psht + psl);
621
 
622
        reg =  psst << 12;
623
        reg |= psl  << 7;
624
        reg |= psht << 16;
625
 
626
        return reg;
627
}
628
 
629
/* ------------------------------------------------------------------------- */
630
 
631
static int m8xx_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
632
{
633
        socket[sock].handler = handler;
634
        socket[sock].info = info;
635
        if (handler == NULL) {
636
                MOD_DEC_USE_COUNT;
637
        }
638
        else {
639
                MOD_INC_USE_COUNT;
640
        }
641
        return 0;
642
}
643
 
644
/* ------------------------------------------------------------------------- */
645
 
646
static int m8xx_get_status(unsigned int lsock, u_int *value)
647
{
648
        socket_info_t *s = &socket[lsock];
649
        u_int pipr, reg;
650
 
651
 
652
        pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
653
 
654
        *value  = ((pipr & (M8XX_PCMCIA_CD1(_slot_)
655
                            | M8XX_PCMCIA_CD2(_slot_))) == 0) ? SS_DETECT : 0;
656
        *value |= (pipr & M8XX_PCMCIA_WP(_slot_)) ? SS_WRPROT : 0;
657
 
658
        if (s->state.flags & SS_IOCARD)
659
                *value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_STSCHG : 0;
660
        else {
661
                *value |= (pipr & M8XX_PCMCIA_RDY(_slot_)) ? SS_READY : 0;
662
                *value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_BATDEAD : 0;
663
                *value |= (pipr & M8XX_PCMCIA_BVD2(_slot_)) ? SS_BATWARN : 0;
664
        }
665
 
666
        if (s->state.Vcc | s->state.Vpp)
667
                *value |= SS_POWERON;
668
 
669
        /*
670
         * Voltage detection:
671
         * This driver only supports 16-Bit pc-cards.
672
         * Cardbus is not handled here.
673
         *
674
         * To determine what voltage to use we must read the VS1 and VS2 pin.
675
         * Depending on what socket type is present,
676
         * different combinations mean different things.
677
         *
678
         * Card Key  Socket Key   VS1   VS2   Card         Vcc for CIS parse
679
         *
680
         * 5V        5V, LV*      NC    NC    5V only       5V (if available)
681
         *
682
         * 5V        5V, LV*      GND   NC    5 or 3.3V     as low as possible
683
         *
684
         * 5V        5V, LV*      GND   GND   5, 3.3, x.xV  as low as possible
685
         *
686
         * LV*       5V            -     -    shall not fit into socket
687
         *
688
         * LV*       LV*          GND   NC    3.3V only     3.3V
689
         *
690
         * LV*       LV*          NC    GND   x.xV          x.xV (if avail.)
691
         *
692
         * LV*       LV*          GND   GND   3.3 or x.xV   as low as possible
693
         *
694
         * *LV means Low Voltage
695
         *
696
         *
697
         * That gives us the following table:
698
         *
699
         * Socket    VS1  VS2   Voltage
700
         *
701
         * 5V        NC   NC    5V
702
         * 5V        NC   GND   none (should not be possible)
703
         * 5V        GND  NC    >= 3.3V
704
         * 5V        GND  GND   >= x.xV
705
         *
706
         * LV        NC   NC    5V   (if available)
707
         * LV        NC   GND   x.xV (if available)
708
         * LV        GND  NC    3.3V
709
         * LV        GND  GND   >= x.xV
710
         *
711
         * So, how do I determine if I have a 5V or a LV
712
         * socket on my board?  Look at the socket!
713
         *
714
         *
715
         * Socket with 5V key:
716
         * ++--------------------------------------------+
717
         * ||                                            |
718
         * ||                                           ||
719
         * ||                                           ||
720
         * |                                             |
721
         * +---------------------------------------------+
722
         *
723
         * Socket with LV key:
724
         * ++--------------------------------------------+
725
         * ||                                            |
726
         * |                                            ||
727
         * |                                            ||
728
         * |                                             |
729
         * +---------------------------------------------+
730
         *
731
         *
732
         * With other words - LV only cards does not fit
733
         * into the 5V socket!
734
         */
735
 
736
        /* read out VS1 and VS2 */
737
 
738
        reg = (pipr & M8XX_PCMCIA_VS_MASK(_slot_))
739
                >> M8XX_PCMCIA_VS_SHIFT(_slot_);
740
 
741
        if(socket_get(_slot_) == PCMCIA_SOCKET_KEY_LV) {
742
                switch(reg) {
743
                case 1: *value |= SS_3VCARD; break; /* GND, NC - 3.3V only */
744
                case 2: *value |= SS_XVCARD; break; /* NC. GND - x.xV only */
745
                };
746
        }
747
 
748
        DEBUG(3,"GetStatus(%d) = %#2.2x\n", lsock, *value);
749
        return 0;
750
}
751
 
752
/* ------------------------------------------------------------------------- */
753
 
754
static int m8xx_inquire_socket(unsigned int lsock, socket_cap_t *cap)
755
{
756
        *cap = capabilities;
757
 
758
        return 0;
759
}
760
 
761
/* ------------------------------------------------------------------------- */
762
 
763
static int m8xx_get_socket(unsigned int lsock, socket_state_t *state)
764
{
765
        *state = socket[lsock].state; /* copy the whole structure */
766
 
767
        DEBUG(3,"GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
768
              "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
769
              state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
770
        return 0;
771
}
772
 
773
/* ------------------------------------------------------------------------- */
774
 
775
static int m8xx_set_socket(unsigned int lsock, socket_state_t *state)
776
{
777
        socket_info_t *s = &socket[lsock];
778
        event_table_t *e;
779
        u_int reg;
780
        u_long flags;
781
 
782
        DEBUG(3, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
783
              "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
784
              state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
785
 
786
        /* First, set voltage - bail out if invalid */
787
 
788
        if(voltage_set(_slot_, state->Vcc, state->Vpp))
789
                return -EINVAL;
790
 
791
 
792
        /* Take care of reset... */
793
 
794
        if(state->flags & SS_RESET)
795
                M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXRESET; /* active high */
796
        else
797
                M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXRESET;
798
 
799
        /* ... and output enable. */
800
 
801
        /* The CxOE signal is connected to a 74541 on the ADS.
802
           I guess most other boards used the ADS as a reference.
803
           I tried to control the CxOE signal with SS_OUTPUT_ENA,
804
           but the reset signal seems connected via the 541.
805
           If the CxOE is left high are some signals tristated and
806
           no pullups are present -> the cards act wierd.
807
           So right now the buffers are enabled if the power is on. */
808
 
809
        if(state->Vcc || state->Vpp)
810
                M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXOE; /* active low */
811
        else
812
                M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXOE;
813
 
814
        /*
815
         * We'd better turn off interrupts before
816
         * we mess with the events-table..
817
         */
818
 
819
        save_flags(flags);
820
        cli();
821
 
822
        /*
823
         * Play around with the interrupt mask to be able to
824
         * give the events the generic pcmcia driver wants us to.
825
         */
826
 
827
        e = &s->events[0];
828
        reg = 0;
829
 
830
        if(state->csc_mask & SS_DETECT) {
831
                e->eventbit = SS_DETECT;
832
                reg |= e->regbit = (M8XX_PCMCIA_CD2(_slot_)
833
                                    | M8XX_PCMCIA_CD1(_slot_));
834
                e++;
835
        }
836
 
837
        if(state->flags & SS_IOCARD) {
838
 
839
                /*
840
                 * I/O card
841
                 */
842
 
843
                if(state->csc_mask & SS_STSCHG) {
844
                        e->eventbit = SS_STSCHG;
845
                        reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
846
                        e++;
847
                }
848
 
849
 
850
                /*
851
                 * If io_irq is non-zero we should enable irq.
852
                 */
853
 
854
                if(state->io_irq) {
855
                        M8XX_PGCRX(_slot_) |=
856
                                mk_int_int_mask(state->io_irq) << 24;
857
 
858
                        /*
859
                         * Strange thing here:
860
                         * The manual does not tell us which interrupt
861
                         * the sources generate.
862
                         * Anyhow, I found out that RDY_L generates IREQLVL.
863
                         *
864
                         * We use level triggerd interrupts, and they don't
865
                         * have to be cleared in PSCR in the interrupt handler.
866
                         */
867
 
868
                        reg |= M8XX_PCMCIA_RDY_L(_slot_);
869
                }
870
                else
871
                        M8XX_PGCRX(_slot_) &= 0x00ffffff;
872
 
873
        }
874
        else {
875
 
876
                /*
877
                 * Memory card
878
                 */
879
 
880
                if(state->csc_mask & SS_BATDEAD) {
881
                        e->eventbit = SS_BATDEAD;
882
                        reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
883
                        e++;
884
                }
885
 
886
                if(state->csc_mask & SS_BATWARN) {
887
                        e->eventbit = SS_BATWARN;
888
                        reg |= e->regbit = M8XX_PCMCIA_BVD2(_slot_);
889
                        e++;
890
                }
891
 
892
                /* What should I trigger on - low/high,raise,fall? */
893
                if(state->csc_mask & SS_READY) {
894
                        e->eventbit = SS_READY;
895
                        reg |= e->regbit = 0; //??
896
                        e++;
897
                }
898
        }
899
 
900
        e->regbit = 0;  /* terminate list */
901
 
902
        /*
903
         * Clear the status changed .
904
         * Port A and Port B share the same port.
905
         * Writing ones will clear the bits.
906
         */
907
 
908
        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = reg;
909
 
910
        /*
911
         * Write the mask.
912
         * Port A and Port B share the same port.
913
         * Need for read-modify-write.
914
         * Ones will enable the interrupt.
915
         */
916
 
917
        reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
918
                & M8XX_PCMCIA_MASK(_slot_);
919
 
920
        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per = reg;
921
 
922
        restore_flags(flags);
923
 
924
        /* copy the struct and modify the copy */
925
 
926
        s->state = *state;
927
 
928
        return 0;
929
}
930
 
931
/* ------------------------------------------------------------------------- */
932
 
933
static int m8xx_get_io_map(unsigned int lsock, struct pccard_io_map *io)
934
{
935
        if(io->map >= PCMCIA_IO_WIN_NO)
936
                return -EINVAL;
937
 
938
        *io = socket[lsock].io_win[io->map]; /* copy the struct */
939
 
940
        DEBUG(3,"GetIOMap(%d, %d) = %#2.2x, %d ns, "
941
              "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
942
              io->speed, io->start, io->stop);
943
        return 0;
944
}
945
 
946
/* ------------------------------------------------------------------------- */
947
 
948
static int m8xx_set_io_map(unsigned int lsock, struct pccard_io_map *io)
949
{
950
        socket_info_t *s = &socket[lsock];
951
        pcmcia_win_t *w;
952
        u_int reg, winnr;
953
 
954
 
955
#define M8XX_SIZE (io->stop - io->start + 1)   
956
#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
957
 
958
        DEBUG(3, "SetIOMap(%d, %d, %#2.2x, %d ns, "
959
              "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
960
              io->speed, io->start, io->stop);
961
 
962
        if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
963
            || (io->stop > 0xffff) || (io->stop < io->start))
964
                return -EINVAL;
965
 
966
        if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
967
                return -EINVAL;
968
 
969
        if(io->flags & MAP_ACTIVE) {
970
 
971
                winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
972
                        + (lsock * PCMCIA_IO_WIN_NO) + io->map;
973
 
974
                /* setup registers */
975
 
976
                w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
977
                w += winnr;
978
 
979
                w->or = 0; /* turn off window first */
980
                w->br = M8XX_BASE;
981
 
982
                reg <<= 27;
983
                reg |= 0x00018 + (_slot_ << 2);
984
 
985
                reg |= m8xx_get_speed(io->speed, 1);
986
 
987
                if(io->flags & MAP_WRPROT)
988
                        reg |= 0x00000002;
989
 
990
                if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
991
                        reg |= 0x00000040;
992
 
993
                if(io->flags & MAP_ACTIVE)
994
                        reg |= 0x00000001;
995
 
996
                w->or = reg;
997
 
998
                DEBUG(3,"Socket %u: Mapped io window %u at %#8.8x, "
999
                      "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
1000
        }
1001
 
1002
 
1003
        /* copy the struct and modify the copy */
1004
 
1005
        s->io_win[io->map] = *io;
1006
        s->io_win[io->map].flags &= (MAP_WRPROT
1007
                                     | MAP_16BIT
1008
                                     | MAP_ACTIVE);
1009
        return 0;
1010
}
1011
 
1012
/* ------------------------------------------------------------------------- */
1013
 
1014
static int m8xx_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
1015
{
1016
        if(mem->map >= PCMCIA_MEM_WIN_NO)
1017
                return -EINVAL;
1018
 
1019
        *mem = socket[lsock].mem_win[mem->map]; /* copy the struct */
1020
 
1021
        DEBUG(3, "GetMemMap(%d, %d) = %#2.2x, %d ns, "
1022
              "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
1023
              mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1024
        return 0;
1025
}
1026
 
1027
/* ------------------------------------------------------------------------- */
1028
 
1029
static int m8xx_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
1030
{
1031
        socket_info_t *s = &socket[lsock];
1032
        pcmcia_win_t *w;
1033
        struct pccard_mem_map *old;
1034
        u_int reg, winnr;
1035
 
1036
        DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
1037
              "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1038
              mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1039
 
1040
        if ((mem->map >= PCMCIA_MEM_WIN_NO) || (mem->sys_start > mem->sys_stop)
1041
            || ((mem->sys_stop - mem->sys_start) >= PCMCIA_MEM_WIN_SIZE)
1042
            || (mem->card_start >= 0x04000000)
1043
            || (mem->sys_start & 0xfff)                /* 4KByte resolution */
1044
            || (mem->card_start & 0xfff))
1045
                return -EINVAL;
1046
 
1047
        if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
1048
                printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
1049
                return -EINVAL;
1050
        }
1051
 
1052
        winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
1053
 
1054
        /* Setup the window in the pcmcia controller */
1055
 
1056
        w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
1057
        w += winnr;
1058
 
1059
        reg <<= 27;
1060
        reg |= _slot_ << 2;
1061
 
1062
        reg |= m8xx_get_speed(mem->speed, 0);
1063
 
1064
        if(mem->flags & MAP_ATTRIB)
1065
                reg |= 0x00000010;
1066
 
1067
        if(mem->flags & MAP_WRPROT)
1068
                reg |= 0x00000002;
1069
 
1070
        if(mem->flags & MAP_16BIT)
1071
                reg |= 0x00000040;
1072
 
1073
        if(mem->flags & MAP_ACTIVE)
1074
                reg |= 0x00000001;
1075
 
1076
        w->or = reg;
1077
 
1078
        DEBUG(3, "Socket %u: Mapped memory window %u at %#8.8x, "
1079
              "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
1080
 
1081
        if(mem->flags & MAP_ACTIVE) {
1082
 
1083
                mem->sys_stop -= mem->sys_start;
1084
 
1085
                /* get the new base address */
1086
 
1087
                mem->sys_start = PCMCIA_MEM_WIN_BASE +
1088
                        (PCMCIA_MEM_WIN_SIZE * winnr)
1089
                        + mem->card_start;
1090
 
1091
                mem->sys_stop += mem->sys_start;
1092
        }
1093
 
1094
DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
1095
              "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1096
              mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1097
 
1098
        /* copy the struct and modify the copy */
1099
 
1100
        old = &s->mem_win[mem->map];
1101
 
1102
        *old = *mem;
1103
        old->flags &= (MAP_ATTRIB
1104
                       | MAP_WRPROT
1105
                       | MAP_16BIT
1106
                       | MAP_ACTIVE);
1107
 
1108
        return 0;
1109
}
1110
 
1111
static int m8xx_sock_init(unsigned int s)
1112
{
1113
        int i;
1114
        pccard_io_map io = { 0, 0, 0, 0, 1 };
1115
        pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
1116
 
1117
        DEBUG(3, "sock_init(%d)\n", s);
1118
 
1119
        mem.sys_stop = 0x1000;
1120
        m8xx_set_socket(s, &dead_socket);
1121
        for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
1122
                io.map = i;
1123
                m8xx_set_io_map(s, &io);
1124
        }
1125
        for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
1126
                mem.map = i;
1127
                m8xx_set_mem_map(s, &mem);
1128
        }
1129
 
1130
        return 0;
1131
 
1132
}
1133
 
1134
static int m8xx_suspend(unsigned int s)
1135
{
1136
                return(m8xx_set_socket(s, &dead_socket));
1137
}
1138
static void m8xx_proc_setup(unsigned int sock, struct proc_dir_entry *base)
1139
{
1140
}
1141
/* ------------------------------------------------------------------------- */
1142
 
1143
static struct pccard_operations m8xx_services = {
1144
        &m8xx_sock_init,
1145
        &m8xx_suspend,
1146
        &m8xx_register_callback,
1147
        &m8xx_inquire_socket,
1148
        &m8xx_get_status,
1149
        &m8xx_get_socket,
1150
        &m8xx_set_socket,
1151
        &m8xx_get_io_map,
1152
        &m8xx_set_io_map,
1153
        &m8xx_get_mem_map,
1154
        &m8xx_set_mem_map,
1155
        &m8xx_proc_setup
1156
};
1157
 
1158
static int __init m8xx_init(void)
1159
{
1160
        servinfo_t serv;
1161
        pcmcia_win_t *w;
1162
        u_int m;
1163
 
1164
        PCMCIA_INFO("%s\n", version);
1165
        CardServices(GetCardServicesInfo, &serv);
1166
        if (serv.Revision != CS_RELEASE_CODE) {
1167
                PCMCIA_ERROR("Card Services release does not match!\n");
1168
                return -1;
1169
        }
1170
 
1171
        PCMCIA_INFO(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
1172
                    " with IRQ %u.\n", pcmcia_schlvl);
1173
 
1174
        /* Configure Status change interrupt */
1175
 
1176
        if(request_8xxirq(pcmcia_schlvl, m8xx_interrupt, 0,
1177
                           "m8xx_pcmcia", NULL)) {
1178
                PCMCIA_ERROR("Cannot allocate IRQ %u for SCHLVL!\n",
1179
                             pcmcia_schlvl);
1180
                return -1;
1181
        }
1182
 
1183
 
1184
        w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
1185
 
1186
        socket[0].slot = _slot_;
1187
 
1188
        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr =
1189
                M8XX_PCMCIA_MASK(_slot_);
1190
        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
1191
                &= ~M8XX_PCMCIA_MASK(_slot_);
1192
 
1193
/* connect interrupt and disable CxOE */
1194
 
1195
        M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE |
1196
                (mk_int_int_mask(pcmcia_schlvl) << 16);
1197
 
1198
/* intialize the fixed memory windows */
1199
 
1200
        for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1201
                w->br = PCMCIA_MEM_WIN_BASE +
1202
                        (PCMCIA_MEM_WIN_SIZE
1203
                         * (m + 0 * PCMCIA_MEM_WIN_NO));
1204
 
1205
                w->or = 0;  /* set to not valid */
1206
 
1207
                DEBUG(3,"Socket %u: MemWin %u: Base 0x%08x.\n",
1208
                      0, m, w->br);
1209
 
1210
                w++;
1211
        }
1212
 
1213
/* turn off voltage */
1214
        voltage_set(_slot_, 0, 0);
1215
 
1216
/* Enable external hardware */
1217
        hardware_enable(_slot_);
1218
 
1219
        if(register_ss_entry(PCMCIA_SOCKETS_NO, &m8xx_services) != 0) {
1220
            PCMCIA_ERROR("register_ss_entry() failed.\n");
1221
            m8xx_shutdown();
1222
            return -ENODEV;
1223
        }
1224
 
1225
        return 0;
1226
}
1227
 
1228
static void __exit m8xx_exit(void)
1229
{
1230
        unregister_ss_entry(&m8xx_services);
1231
 
1232
        m8xx_shutdown();
1233
}
1234
 
1235
module_init(m8xx_init);
1236
module_exit(m8xx_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.