1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _SCC_H
14#define _SCC_H
15
16#include <linux/delay.h>
17
18
19
20
21
22
23
24#define TIOCGATSCC 0x54c0
25#define TIOCSATSCC 0x54c1
26#define TIOCDATSCC 0x54c2
27
28
29
30#define CLK_RTxC 0
31#define CLK_TRxC 1
32#define CLK_PCLK 2
33
34
35
36
37
38#define SCC_BAUD_BASE_TIMC 19200
39#define SCC_BAUD_BASE_BCLK 153600
40#define SCC_BAUD_BASE_PCLK4 229500
41#define SCC_BAUD_BASE_PCLK 503374
42#define SCC_BAUD_BASE_NONE 0
43
44
45
46
47struct scc_clock_config {
48 unsigned RTxC_base;
49 unsigned TRxC_base;
50 unsigned PCLK_base;
51 struct {
52 unsigned clksrc;
53 unsigned divisor;
54
55 } baud_table[17];
56
57
58
59
60
61
62};
63
64
65
66
67
68
69
70
71
72
73
74
75struct scc_port {
76 struct gs_port gs;
77 volatile unsigned char *ctrlp;
78 volatile unsigned char *datap;
79 int x_char;
80 int c_dcd;
81 int channel;
82 struct scc_port *port_a;
83 struct scc_port *port_b;
84};
85
86#define SCC_MAGIC 0x52696368
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102#define COMMAND_REG 0
103#define INT_AND_DMA_REG 1
104#define INT_VECTOR_REG 2
105#define RX_CTRL_REG 3
106#define AUX1_CTRL_REG 4
107#define TX_CTRL_REG 5
108#define SYNC_ADR_REG 6
109#define SYNC_CHAR_REG 7
110#define SDLC_OPTION_REG 33
111#define TX_DATA_REG 8
112#define MASTER_INT_CTRL 9
113#define AUX2_CTRL_REG 10
114#define CLK_CTRL_REG 11
115#define TIMER_LOW_REG 12
116#define TIMER_HIGH_REG 13
117#define DPLL_CTRL_REG 14
118#define INT_CTRL_REG 15
119
120#define STATUS_REG 16
121#define SPCOND_STATUS_REG 17
122
123#define CURR_VECTOR_REG 18
124#define INT_PENDING_REG 19
125
126
127#define FS_FIFO_LOW_REG 22
128#define FS_FIFO_HIGH_REG 23
129#define RX_DATA_REG 24
130
131#define DPLL_STATUS_REG 26
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148#define CR_RX_CRC_RESET 0x40
149#define CR_TX_CRC_RESET 0x80
150#define CR_TX_UNDERRUN_RESET 0xc0
151
152#define CR_EXTSTAT_RESET 0x10
153#define CR_SEND_ABORT 0x18
154#define CR_ENAB_INT_NEXT_RX 0x20
155#define CR_TX_PENDING_RESET 0x28
156#define CR_ERROR_RESET 0x30
157#define CR_HIGHEST_IUS_RESET 0x38
158
159
160
161
162#define IDR_EXTSTAT_INT_ENAB 0x01
163#define IDR_TX_INT_ENAB 0x02
164#define IDR_PARERR_AS_SPCOND 0x04
165
166#define IDR_RX_INT_DISAB 0x00
167#define IDR_RX_INT_FIRST 0x08
168#define IDR_RX_INT_ALL 0x10
169#define IDR_RX_INT_SPCOND 0x18
170#define IDR_RX_INT_MASK 0x18
171
172#define IDR_WAITREQ_RX 0x20
173#define IDR_WAITREQ_IS_REQ 0x40
174#define IDR_WAITREQ_ENAB 0x80
175
176
177
178
179#define RCR_RX_ENAB 0x01
180#define RCR_DISCARD_SYNC_CHARS 0x02
181#define RCR_ADDR_SEARCH 0x04
182#define RCR_CRC_ENAB 0x08
183#define RCR_SEARCH_MODE 0x10
184#define RCR_AUTO_ENAB_MODE 0x20
185
186#define RCR_CHSIZE_MASK 0xc0
187#define RCR_CHSIZE_5 0x00
188#define RCR_CHSIZE_6 0x40
189#define RCR_CHSIZE_7 0x80
190#define RCR_CHSIZE_8 0xc0
191
192
193
194
195#define A1CR_PARITY_MASK 0x03
196#define A1CR_PARITY_NONE 0x00
197#define A1CR_PARITY_ODD 0x01
198#define A1CR_PARITY_EVEN 0x03
199
200#define A1CR_MODE_MASK 0x0c
201#define A1CR_MODE_SYNCR 0x00
202#define A1CR_MODE_ASYNC_1 0x04
203#define A1CR_MODE_ASYNC_15 0x08
204#define A1CR_MODE_ASYNC_2 0x0c
205
206#define A1CR_SYNCR_MODE_MASK 0x30
207#define A1CR_SYNCR_MONOSYNC 0x00
208#define A1CR_SYNCR_BISYNC 0x10
209#define A1CR_SYNCR_SDLC 0x20
210#define A1CR_SYNCR_EXTCSYNC 0x30
211
212#define A1CR_CLKMODE_MASK 0xc0
213#define A1CR_CLKMODE_x1 0x00
214#define A1CR_CLKMODE_x16 0x40
215#define A1CR_CLKMODE_x32 0x80
216#define A1CR_CLKMODE_x64 0xc0
217
218
219
220
221#define TCR_TX_CRC_ENAB 0x01
222#define TCR_RTS 0x02
223#define TCR_USE_CRC_CCITT 0x00
224#define TCR_USE_CRC_16 0x04
225#define TCR_TX_ENAB 0x08
226#define TCR_SEND_BREAK 0x10
227
228#define TCR_CHSIZE_MASK 0x60
229#define TCR_CHSIZE_5 0x00
230#define TCR_CHSIZE_6 0x20
231#define TCR_CHSIZE_7 0x40
232#define TCR_CHSIZE_8 0x60
233
234#define TCR_DTR 0x80
235
236
237
238
239#define SOR_AUTO_TX_ENAB 0x01
240#define SOR_AUTO_EOM_RESET 0x02
241#define SOR_AUTO_RTS_MODE 0x04
242#define SOR_NRZI_DISAB_HIGH 0x08
243#define SOR_ALT_DTRREQ_TIMING 0x10
244#define SOR_READ_CRC_CHARS 0x20
245#define SOR_EXTENDED_REG_ACCESS 0x40
246
247
248
249
250#define MIC_VEC_INCL_STAT 0x01
251#define MIC_NO_VECTOR 0x02
252#define MIC_DISAB_LOWER_CHAIN 0x04
253#define MIC_MASTER_INT_ENAB 0x08
254#define MIC_STATUS_HIGH 0x10
255#define MIC_IGN_INTACK 0x20
256
257#define MIC_NO_RESET 0x00
258#define MIC_CH_A_RESET 0x40
259#define MIC_CH_B_RESET 0x80
260#define MIC_HARD_RESET 0xc0
261
262
263
264
265#define A2CR_SYNC_6 0x01
266#define A2CR_LOOP_MODE 0x02
267#define A2CR_ABORT_ON_UNDERRUN 0x04
268#define A2CR_MARK_IDLE 0x08
269#define A2CR_GO_ACTIVE_ON_POLL 0x10
270
271#define A2CR_CODING_MASK 0x60
272#define A2CR_CODING_NRZ 0x00
273#define A2CR_CODING_NRZI 0x20
274#define A2CR_CODING_FM1 0x40
275#define A2CR_CODING_FM0 0x60
276
277#define A2CR_PRESET_CRC_1 0x80
278
279
280
281
282#define CCR_TRxCOUT_MASK 0x03
283#define CCR_TRxCOUT_XTAL 0x00
284#define CCR_TRxCOUT_TXCLK 0x01
285#define CCR_TRxCOUT_BRG 0x02
286#define CCR_TRxCOUT_DPLL 0x03
287
288#define CCR_TRxC_OUTPUT 0x04
289
290#define CCR_TXCLK_MASK 0x18
291#define CCR_TXCLK_RTxC 0x00
292#define CCR_TXCLK_TRxC 0x08
293#define CCR_TXCLK_BRG 0x10
294#define CCR_TXCLK_DPLL 0x18
295
296#define CCR_RXCLK_MASK 0x60
297#define CCR_RXCLK_RTxC 0x00
298#define CCR_RXCLK_TRxC 0x20
299#define CCR_RXCLK_BRG 0x40
300#define CCR_RXCLK_DPLL 0x60
301
302#define CCR_RTxC_XTAL 0x80
303
304
305
306
307#define DCR_BRG_ENAB 0x01
308#define DCR_BRG_USE_PCLK 0x02
309#define DCR_DTRREQ_IS_REQ 0x04
310#define DCR_AUTO_ECHO 0x08
311#define DCR_LOCAL_LOOPBACK 0x10
312
313#define DCR_DPLL_EDGE_SEARCH 0x20
314#define DCR_DPLL_ERR_RESET 0x40
315#define DCR_DPLL_DISAB 0x60
316#define DCR_DPLL_CLK_BRG 0x80
317#define DCR_DPLL_CLK_RTxC 0xa0
318#define DCR_DPLL_FM 0xc0
319#define DCR_DPLL_NRZI 0xe0
320
321
322
323
324#define ICR_OPTIONREG_SELECT 0x01
325#define ICR_ENAB_BRG_ZERO_INT 0x02
326#define ICR_USE_FS_FIFO 0x04
327#define ICR_ENAB_DCD_INT 0x08
328#define ICR_ENAB_SYNC_INT 0x10
329#define ICR_ENAB_CTS_INT 0x20
330#define ICR_ENAB_UNDERRUN_INT 0x40
331#define ICR_ENAB_BREAK_INT 0x80
332
333
334
335
336#define SR_CHAR_AVAIL 0x01
337#define SR_BRG_ZERO 0x02
338#define SR_TX_BUF_EMPTY 0x04
339#define SR_DCD 0x08
340#define SR_SYNC_ABORT 0x10
341#define SR_CTS 0x20
342#define SR_TX_UNDERRUN 0x40
343#define SR_BREAK 0x80
344
345
346
347
348#define SCSR_ALL_SENT 0x01
349#define SCSR_RESIDUAL_MASK 0x0e
350#define SCSR_PARITY_ERR 0x10
351#define SCSR_RX_OVERRUN 0x20
352#define SCSR_CRC_FRAME_ERR 0x40
353#define SCSR_END_OF_FRAME 0x80
354
355
356
357
358#define IPR_B_EXTSTAT 0x01
359#define IPR_B_TX 0x02
360#define IPR_B_RX 0x04
361#define IPR_A_EXTSTAT 0x08
362#define IPR_A_TX 0x10
363#define IPR_A_RX 0x20
364
365
366
367
368#define FFHR_CNT_MASK 0x3f
369#define FFHR_IS_FROM_FIFO 0x40
370#define FFHR_FIFO_OVERRUN 0x80
371
372
373
374
375#define DSR_ON_LOOP 0x02
376#define DSR_ON_LOOP_SENDING 0x10
377#define DSR_TWO_CLK_MISSING 0x40
378#define DSR_ONE_CLK_MISSING 0x80
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394#define scc_reg_delay() \
395 do { \
396 if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147) \
397 __asm__ __volatile__ ( " nop; nop"); \
398 else if (MACH_IS_ATARI) \
399 __asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\
400 } while (0)
401
402static unsigned char scc_shadow[2][16];
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442static __inline__ void _SCCwrite(
443 struct scc_port *port,
444 unsigned char *shadow,
445 volatile unsigned char *_scc_del,
446 int regno,
447 unsigned char val, int final_delay )
448{
449 switch( regno ) {
450
451 case COMMAND_REG:
452
453 *port->ctrlp = val;
454 break;
455
456 case SYNC_CHAR_REG:
457
458 if (shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT) {
459 *port->ctrlp = 15;
460 shadow[INT_CTRL_REG] &= ~ICR_OPTIONREG_SELECT;
461 scc_reg_delay();
462 *port->ctrlp = shadow[INT_CTRL_REG];
463 scc_reg_delay();
464 }
465 goto normal_case;
466
467 case SDLC_OPTION_REG:
468
469 if (!(shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT)) {
470 *port->ctrlp = 15;
471 shadow[INT_CTRL_REG] |= ICR_OPTIONREG_SELECT;
472 scc_reg_delay();
473 *port->ctrlp = shadow[INT_CTRL_REG];
474 scc_reg_delay();
475 }
476 *port->ctrlp = 7;
477 shadow[8] = val;
478 scc_reg_delay();
479 *port->ctrlp = val;
480 break;
481
482 case TX_DATA_REG:
483
484 if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147)
485 {
486 *port->ctrlp = regno;
487 scc_reg_delay();
488 *port->ctrlp = val;
489 }
490 else
491 *port->datap = val;
492 break;
493
494 case MASTER_INT_CTRL:
495 *port->ctrlp = regno;
496 val &= 0x3f;
497 scc_shadow[0][regno] = val;
498 scc_reg_delay();
499 *port->ctrlp = val;
500 break;
501
502 case DPLL_CTRL_REG:
503 *port->ctrlp = regno;
504 val &= 0x1f;
505 shadow[regno] = val;
506 scc_reg_delay();
507 *port->ctrlp = val;
508 break;
509
510 case 1 ... 6:
511 case 10 ... 13:
512 case 15:
513 normal_case:
514 *port->ctrlp = regno;
515 shadow[regno] = val;
516 scc_reg_delay();
517 *port->ctrlp = val;
518 break;
519
520 default:
521 printk( "Bad SCC write access to WR%d\n", regno );
522 break;
523
524 }
525
526 if (final_delay)
527 scc_reg_delay();
528}
529
530
531static __inline__ unsigned char _SCCread(
532 struct scc_port *port,
533 unsigned char *shadow,
534 volatile unsigned char *_scc_del,
535 int regno, int final_delay )
536{
537 unsigned char rv;
538
539 switch( regno ) {
540
541
542 case STATUS_REG:
543 rv = *port->ctrlp;
544 break;
545
546 case INT_PENDING_REG:
547
548 port = port->port_a;
549 goto normal_case;
550
551 case RX_DATA_REG:
552
553 if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147)
554 {
555 *port->ctrlp = 8;
556 scc_reg_delay();
557 rv = *port->ctrlp;
558 }
559 else
560 rv = *port->datap;
561 break;
562
563 case CURR_VECTOR_REG:
564
565 port = port->port_b;
566 goto normal_case;
567
568
569 case 1 ... 7:
570 case 10 ... 15:
571 return shadow[regno];
572
573
574 case SDLC_OPTION_REG:
575 return shadow[8];
576
577
578 case MASTER_INT_CTRL:
579 return scc_shadow[0][9];
580
581 default:
582 printk( "Bad SCC read access to %cR%d\n", (regno & 16) ? 'R' : 'W',
583 regno & ~16 );
584 break;
585
586 case SPCOND_STATUS_REG:
587 case FS_FIFO_LOW_REG:
588 case FS_FIFO_HIGH_REG:
589 case DPLL_STATUS_REG:
590 normal_case:
591 *port->ctrlp = regno & 0x0f;
592 scc_reg_delay();
593 rv = *port->ctrlp;
594 break;
595
596 }
597
598 if (final_delay)
599 scc_reg_delay();
600 return rv;
601}
602
603#define SCC_ACCESS_INIT(port) \
604 unsigned char *_scc_shadow = &scc_shadow[port->channel][0]
605
606#define SCCwrite(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),1)
607#define SCCwrite_NB(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),0)
608#define SCCread(reg) _SCCread(port,_scc_shadow,scc_del,(reg),1)
609#define SCCread_NB(reg) _SCCread(port,_scc_shadow,scc_del,(reg),0)
610
611#define SCCmod(reg,and,or) SCCwrite((reg),(SCCread(reg)&(and))|(or))
612
613#endif
614