source: rtems/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c @ c0357a8

4.104.114.95
Last change on this file since c0357a8 was c0357a8, checked in by Joel Sherrill <joel.sherrill@…>, on 05/22/08 at 20:34:20

2008-05-22 Joel Sherrill <joel.sherrill@…>

  • console/mc68360_scc.c: Remove explicit switch and call termios_baud_to_number().
  • Property mode set to 100644
File size: 23.2 KB
Line 
1/*  This file contains the termios TTY driver for the Motorola MC68360 SCC ports.
2 *
3 *  COPYRIGHT (c) 1989-1999.
4 *  On-Line Applications Research Corporation (OAR).
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 *
10 *  $Id$
11 */
12
13#include <stdio.h>
14#include <termios.h>
15#include <bsp.h>
16#include <libcpu/io.h>
17#include <rtems/libio.h>
18#include <bsp/pci.h>
19#include <bsp/irq.h>
20#include <libchip/serial.h>
21#include "m68360.h"
22#include <libchip/sersupp.h>
23#include <stdlib.h>
24#include <rtems/bspIo.h>
25#include <rtems/termiostypes.h>
26#include <string.h>
27
28#define MC68360_LENGHT_SIZE 100
29int mc68360_length_array[ MC68360_LENGHT_SIZE ];
30int mc68360_length_count=0;
31
32void mc68360_Show_length_array() {
33  int i;
34  for (i=0; i<MC68360_LENGHT_SIZE; i++)
35    printf(" %d", mc68360_length_array[i] );
36  printf("\n\n");
37}
38
39M68360_t    M68360_chips = NULL;
40
41#define SYNC     eieio
42
43void mc68360_scc_nullFunc() {}
44
45uint8_t scc_read8(
46  const char       *name,
47  volatile uint8_t *address
48)
49{
50  uint8_t value;
51
52#ifdef DEBUG_360
53  printk( "RD8 %s 0x%08x ", name, address );
54#endif
55  value = *address;
56#ifdef DEBUG_360
57  printk( "0x%02x\n", value );
58#endif
59
60  return value;
61}
62
63void scc_write8(
64  const char       *name,
65  volatile uint8_t *address,
66  uint8_t           value
67)
68{
69#ifdef DEBUG_360
70  printk( "WR8 %s 0x%08x 0x%02x\n", name, address, value );
71#endif
72  *address = value;
73}
74
75
76uint16_t scc_read16(
77  const char        *name,
78  volatile uint16_t *address
79)
80{
81  uint16_t value;
82
83#ifdef DEBUG_360
84  printk( "RD16 %s 0x%08x ", name, address );
85#endif
86  value = *address;
87#ifdef DEBUG_360
88  printk( "0x%04x\n", value );
89#endif
90
91  return value;
92}
93
94void scc_write16(
95  const char        *name,
96  volatile uint16_t *address,
97  uint16_t           value
98)
99{
100#ifdef DEBUG_360
101  printk( "WR16 %s 0x%08x 0x%04x\n", name, address, value );
102#endif
103  *address = value;
104}
105
106
107uint32_t scc_read32(
108  const char        *name,
109  volatile uint32_t *address
110)
111{
112  uint32_t value;
113
114#ifdef DEBUG_360
115  printk( "RD32 %s 0x%08x ", name, address );
116#endif
117  value = *address;
118#ifdef DEBUG_360
119  printk( "0x%08x\n", value );
120#endif
121
122  return value;
123}
124
125void scc_write32(
126  const char        *name,
127  volatile uint32_t *address,
128  uint32_t           value
129)
130{
131#ifdef DEBUG_360
132  printk( "WR32 %s 0x%08x 0x%08x\n", name, address, value );
133#endif
134  *address = value;
135}
136
137void mc68360_sccShow_Regs(int minor){
138  M68360_serial_ports_t  ptr;
139  ptr   = Console_Port_Tbl[minor].pDeviceParams;
140 
141  printk( "scce 0x%08x", &ptr->pSCCR->scce );
142  printk( " 0x%04x\n", ptr->pSCCR->scce );
143 
144}
145
146#define TX_BUFFER_ADDRESS( _ptr ) \
147  ((char *)ptr->txBuf - (char *)ptr->chip->board_data->baseaddr)
148#define RX_BUFFER_ADDRESS( _ptr ) \
149  ((char *)ptr->rxBuf - (char *)ptr->chip->board_data->baseaddr)
150
151
152/**************************************************************************
153 * Function: mc68360_sccBRGC                                             *
154 **************************************************************************
155 * Description:                                                           *
156 *                                                                        *
157 *    This function is called to compute the divisor register values for  *
158 *    a given baud rate.                                                  *
159 *                                                                        *
160 *                                                                        *
161 * Inputs:                                                                *
162 *                                                                        *
163 *    int baud  - Baud rate (in bps).                                     *
164 *                                                                        *
165 * Output:                                                                *
166 *                                                                        *
167 *    int  - baud rate generator configuration.                           *
168 *                                                                        *
169 **************************************************************************/
170static int
171mc68360_sccBRGC(int baud, int m360_clock_rate)
172{
173   int data;
174
175  /*
176   * configure baud rate generator for 16x bit rate, where.....
177   * b    =   desired baud rate
178   * clk  =   system clock (33mhz)
179   * d    =   clock dividor value
180   *
181   * for b > 300  :   d = clk/(b*16)
182   * for b<= 300  :   d = (clk/ (b*16*16))-1)
183   */
184
185  SYNC();
186  if( baud > 300 ) data = 33333333 / (baud * 16 );
187  else             data = (33333333 / (baud * 16 * 16) ) - 1;
188  data *= 2;
189  data &= 0x00001ffe ;
190                                                                                             
191  /* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
192  data |= ((baud>300)? 0 : 1 ) ;
193  data |= 0x010000 ;
194                                                                                             
195  return data;
196}
197
198
199/**************************************************************************
200 * Function: sccInterruptHandler                                          *
201 **************************************************************************
202 * Description:                                                           *
203 *                                                                        *
204 *    This is the interrupt service routine for the console UART.  It     *
205 *    handles both receive and transmit interrupts.  The bulk of the      *
206 *    work is done by termios.                                            *
207 *                                                                        *
208 * Inputs:                                                                *
209 *                                                                        *
210 *    chip  - structure of chip specific information                      *
211 *                                                                        *
212 * Output:                                                                *
213 *                                                                        *
214 *    none                                                                *
215 *                                                                        *
216 **************************************************************************/
217void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle )
218{
219  volatile m360_t    *m360;
220  int                port;
221  uint16_t           status;
222  uint16_t           length;
223  int                i;
224  char               data;
225  int                clear_isr;
226  M68360_t           chip = (M68360_t)handle;
227
228  for (port=0; port<4; port++) {
229
230      clear_isr = FALSE;
231      m360  = chip->m360;
232
233      /*
234       * Handle a RX interrupt.
235       */
236      if ( scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x1)
237      {
238        clear_isr = TRUE;
239        scc_write16("scce", &chip->port[port].pSCCR->scce, 0x1 );
240        status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
241        while ((status & M360_BD_EMPTY) == 0)
242        {
243           length= scc_read16("sccRxBd->length",&chip->port[port].sccRxBd->length);
244           for (i=0;i<length;i++) {
245             data= chip->port[port].rxBuf[i];
246             rtems_termios_enqueue_raw_characters(
247               Console_Port_Data[ chip->port[port].minor ].termios_data,
248               &data,
249               1);
250           }
251           scc_write16( "sccRxBd->status", &chip->port[port].sccRxBd->status,
252                        M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
253           status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
254        }
255      }
256
257      /*
258       * Handle a TX interrupt.
259       */
260      if (scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x2)
261      {
262        clear_isr = TRUE;
263        scc_write16("scce", &chip->port[port].pSCCR->scce, 0x2);
264        status = scc_read16("sccTxBd->status", &chip->port[port].sccTxBd->status);
265        if ((status & M360_BD_EMPTY) == 0)
266        {
267           scc_write16("sccTxBd->status",&chip->port[port].sccTxBd->status,0);
268           rtems_termios_dequeue_characters(
269             Console_Port_Data[chip->port[port].minor].termios_data,
270             chip->port[port].sccTxBd->length);
271        }
272      }
273
274      /*
275       * Clear SCC interrupt-in-service bit.
276       */
277      if ( clear_isr )
278        scc_write32( "cisr", &m360->cisr, (0x80000000 >> chip->port[port].channel) );
279  }
280}
281
282/*
283 *  mc68360_scc_open
284 *
285 *  This function opens a port for communication.
286 *
287 *  Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
288 */
289
290int mc68360_scc_open(
291  int      major,
292  int      minor,
293  void    * arg
294)
295{
296
297  return RTEMS_SUCCESSFUL;
298}
299
300/*
301 *  mc68360_scc_initialize_interrupts
302 *
303 *  This routine initializes the console's receive and transmit
304 *  ring buffers and loads the appropriate vectors to handle the interrupts.
305 */
306
307void mc68360_scc_initialize_interrupts(int minor)
308{
309  M68360_serial_ports_t  ptr;
310  volatile m360_t       *m360;
311  uint32_t               data;
312  uint32_t               buffers_start;
313  uint32_t               tmp_u32;
314
315#ifdef DEBUG_360
316  printk("mc68360_scc_initialize_interrupts: minor %d\n", minor );
317  printk("Console_Port_Tbl[minor].pDeviceParams 0x%08x\n",
318    Console_Port_Tbl[minor].pDeviceParams );
319#endif
320
321  ptr   = Console_Port_Tbl[minor].pDeviceParams;
322  m360  = ptr->chip->m360;
323#ifdef DEBUG_360
324  printk("m360 0x%08x baseaddr 0x%08x\n",
325     m360, ptr->chip->board_data->baseaddr);
326#endif
327
328  buffers_start = ptr->chip->board_data->baseaddr + 0x00200000 +
329            ( (M68360_RX_BUF_SIZE + M68360_TX_BUF_SIZE) * (ptr->channel-1));
330  ptr->rxBuf = (uint8_t *) buffers_start;
331  ptr->txBuf = (uint8_t *)(buffers_start + M68360_RX_BUF_SIZE);
332#ifdef DEBUG_360
333  printk("rxBuf 0x%08x  txBuf 0x%08x\n", ptr->rxBuf, ptr->txBuf );
334#endif
335  /*
336   * Set Channel Drive Enable bits in EPLD
337   */
338  data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
339  SYNC();
340  data |= (PMCQ1_DRIVER_ENABLE_3 | PMCQ1_DRIVER_ENABLE_2 |
341           PMCQ1_DRIVER_ENABLE_1 | PMCQ1_DRIVER_ENABLE_0);
342  PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE, data);
343  data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
344  SYNC();
345
346  /*
347   * Disable the receiver and the transmitter.
348   */
349
350  SYNC();
351  tmp_u32 = scc_read32( "gsmr_l", &ptr->pSCCR->gsmr_l );
352  tmp_u32 &= (~(M360_GSMR_ENR | M360_GSMR_ENT ) ) ;
353  scc_write32( "gsmr_l", &ptr->pSCCR->gsmr_l, tmp_u32 );
354
355  /*
356   * Disable Interrupt Error and Interrupt Breakpoint
357   * Set SAID to 4 XXX - Shouldn't it be 7 for slave mode
358   * Set SAISM to 7
359   */
360  SYNC();
361  scc_write16( "sdcr", &m360->sdcr, 0x0740 );
362
363  /*
364   * Clear status -- reserved interrupt, SDMA channel error, SDMA breakpoint
365   */
366  scc_write8( "sdsr", &m360->sdsr, 0x07 );
367  SYNC();
368
369  /*
370   * Initialize timer information in RISC Controller Configuration Register
371   */
372  scc_write16( "rccr", &m360->rccr, 0x8100 );
373  SYNC();
374
375  /*
376   * XXX
377   */
378  scc_write16( "papar", &m360->papar, 0xffff );
379  scc_write16( "padir", &m360->padir, 0x5500 ); /* From Memo    */
380  scc_write16( "paodr", &m360->paodr, 0x0000 );
381  SYNC();
382
383  /*
384   * XXX
385   */
386  scc_write32( "pbpar", &m360->pbpar, 0x00000000 );
387  scc_write32( "pbdir", &m360->pbdir, 0x0003ffff );
388  scc_write32( "pbdat", &m360->pbdat, 0x0000003f );
389  SYNC();
390
391  /*
392   * XXX
393   */
394  scc_write16( "pcpar", &m360->pcpar, 0x0000 );
395  scc_write16( "pcdir", &m360->pcdir, 0x0000 );
396  scc_write16( "pcso", &m360->pcso, 0x0000 );
397  SYNC();
398
399  /*
400   * configure baud rate generator for 16x bit rate, where.....
401   * b    =   desired baud rate
402   * clk  =   system clock (33mhz)
403   * d    =   clock dividor value
404   *
405   * for b > 300  :   d = clk/(b*16)
406   * for b<= 300  :   d = (clk/ (b*16*16))-1)
407   */
408  SYNC();
409  if( ptr->baud > 300 ) data = 33333333 / (ptr->baud * 16 );
410  else                  data = (33333333 / (ptr->baud * 16 * 16) ) - 1;
411  data *= 2 ;
412  data &= 0x00001ffe ;
413
414  /* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
415  data |= ((ptr->baud>300)? 0 : 1 ) ;
416  data |= 0x010000 ;
417
418  scc_write32( "pBRGC", ptr->pBRGC, data );
419
420  data =  (((ptr->channel-1)*8) | (ptr->channel-1)) ;
421  data = data << ((ptr->channel-1)*8) ;
422  data |= scc_read32( "sicr", &m360->sicr );
423  scc_write32( "sicr", &m360->sicr, data );
424
425  /*
426   * initialise SCC parameter ram
427   */
428  SYNC();
429  scc_write16( "pSCCB->rbase", &ptr->pSCCB->rbase,
430               (char *)(ptr->sccRxBd) - (char *)m360 );
431  scc_write16( "pSCCB->tbase", &ptr->pSCCB->tbase,
432               (char *)(ptr->sccTxBd) - (char *)m360 );
433
434  scc_write8( "pSCCB->rfcr", &ptr->pSCCB->rfcr, 0x15 ); /* 0x15 0x18 */
435  scc_write8( "pSCCB->tfcr", &ptr->pSCCB->tfcr, 0x15 ); /* 0x15 0x18 */
436
437  scc_write16( "pSCCB->mrblr", &ptr->pSCCB->mrblr, M68360_RX_BUF_SIZE );
438
439  /*
440   * initialise tx and rx scc parameters
441   */
442  SYNC();
443  data  = M360_CR_INIT_TX_RX_PARAMS | 0x01;
444  data |= (M360_CR_CH_NUM * (ptr->channel-1) );
445  scc_write16( "CR", &m360->cr, data );
446
447  /*
448   * initialise uart specific parameter RAM
449   */
450  SYNC();
451  scc_write16( "pSCCB->un.uart.max_idl", &ptr->pSCCB->un.uart.max_idl, 15000 );
452  scc_write16( "pSCCB->un.uart.brkcr", &ptr->pSCCB->un.uart.brkcr, 0x0001 );
453  scc_write16( "pSCCB->un.uart.parec", &ptr->pSCCB->un.uart.parec, 0x0000 );
454
455  scc_write16( "pSCCB->un,uart.frmec", &ptr->pSCCB->un.uart.frmec, 0x0000 );
456
457  scc_write16( "pSCCB->un.uart.nosec", &ptr->pSCCB->un.uart.nosec, 0x0000 );
458  scc_write16( "pSCCB->un.uart.brkec", &ptr->pSCCB->un.uart.brkec, 0x0000 );
459  scc_write16( "pSCCB->un.uart.uaddr0", &ptr->pSCCB->un.uart.uaddr[0], 0x0000 );
460  scc_write16( "pSCCB->un.uart.uaddr1", &ptr->pSCCB->un.uart.uaddr[1], 0x0000 );
461  scc_write16( "pSCCB->un.uart.toseq", &ptr->pSCCB->un.uart.toseq, 0x0000 );
462  scc_write16( "pSCCB->un.uart.char0",
463               &ptr->pSCCB->un.uart.character[0], 0x0039 );
464  scc_write16( "pSCCB->un.uart.char1",
465               &ptr->pSCCB->un.uart.character[1], 0x8000 );
466  scc_write16( "pSCCB->un.uart.char2",
467               &ptr->pSCCB->un.uart.character[2], 0x8000 );
468  scc_write16( "pSCCB->un.uart.char3",
469               &ptr->pSCCB->un.uart.character[3], 0x8000 );
470  scc_write16( "pSCCB->un.uart.char4",
471               &ptr->pSCCB->un.uart.character[4], 0x8000 );
472  scc_write16( "pSCCB->un.uart.char5",
473               &ptr->pSCCB->un.uart.character[5], 0x8000 );
474  scc_write16( "pSCCB->un.uart.char6",
475               &ptr->pSCCB->un.uart.character[6], 0x8000 );
476  scc_write16( "pSCCB->un.uart.char7",
477               &ptr->pSCCB->un.uart.character[7], 0x8000 );
478
479  scc_write16( "pSCCB->un.uart.rccm", &ptr->pSCCB->un.uart.rccm, 0xc0ff );
480
481  /*
482   * setup buffer descriptor stuff
483   */
484  SYNC();
485  scc_write16( "sccRxBd->status", &ptr->sccRxBd->status, 0x0000 );
486  SYNC();
487  scc_write16( "sccRxBd->length", &ptr->sccRxBd->length, 0x0000 );
488  scc_write16( "sccRxBd->status", &ptr->sccRxBd->status,
489               M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
490  /* XXX Radstone Example writes RX buffer ptr as two u16's */
491  scc_write32( "sccRxBd->buffer", &ptr->sccRxBd->buffer,
492               RX_BUFFER_ADDRESS( ptr ) );
493
494  SYNC();
495  scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0x0000 );
496  SYNC();
497  scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, 0x0000 );
498  /* XXX Radstone Example writes TX buffer ptr as two u16's */
499  scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
500               TX_BUFFER_ADDRESS( ptr ) );
501
502  /*
503   * clear previous events and set interrupt priorities
504   */
505  scc_write16( "pSCCR->scce", &ptr->pSCCR->scce, 0x1bef ); /* From memo   */
506  SYNC();
507  SYNC();
508  scc_write32( "cicr", &m360->cicr, 0x001b9f40 );
509  SYNC();
510
511  /* scc_write32( "cicr", &m360->cicr, scc_read32( "cicr", &m360->cicr ) ); */
512
513  scc_write16( "pSCCR->sccm", &ptr->pSCCR->sccm, M360_SCCE_TX | M360_SCCE_RX );
514
515  data = scc_read32("cimr", &m360->cimr); 
516  data |= (0x80000000 >> ptr->channel);
517  scc_write32( "cimr", &m360->cimr, data );
518  SYNC();
519  scc_write32( "cipr", &m360->cipr, scc_read32( "cipr", &m360->cipr ) );
520
521  scc_write32( "pSCCR->gsmr_h", &ptr->pSCCR->gsmr_h, M360_GSMR_RFW );
522  scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
523        (M360_GSMR_TDCR_16X | M360_GSMR_RDCR_16X | M360_GSMR_MODE_UART) );
524
525  scc_write16( "pSCCR->dsr", &ptr->pSCCR->dsr, 0x7e7e );
526  SYNC();
527
528  scc_write16( "pSCCR->psmr", &ptr->pSCCR->psmr,
529               (M360_PSMR_CL8 | M360_PSMR_UM_NORMAL | M360_PSMR_TPM_ODD) );
530  SYNC();
531
532  /*
533   * Enable the receiver and the transmitter.
534   */
535
536  SYNC();
537  data = scc_read32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l);
538  scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
539               (data | M360_GSMR_ENR | M360_GSMR_ENT) );
540
541  data  = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK );
542  data &= (~PMCQ1_INT_MASK_QUICC);
543  PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK, data );
544 
545  data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS );
546  data &= (~PMCQ1_INT_STATUS_QUICC);
547  PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS, data );
548}
549
550/*
551 *  mc68360_scc_write_support_int
552 *
553 *  Console Termios output entry point when using interrupt driven output.
554 */
555
556int mc68360_scc_write_support_int(
557  int         minor,
558  const char *buf,
559  int         len
560)
561{
562  rtems_interrupt_level  Irql;
563  M68360_serial_ports_t  ptr;
564
565  mc68360_length_array[ mc68360_length_count ] = len;
566  mc68360_length_count++;
567  if ( mc68360_length_count >= MC68360_LENGHT_SIZE )
568    mc68360_length_count=0;
569
570  ptr   = Console_Port_Tbl[minor].pDeviceParams;
571
572  /*
573   *  We are using interrupt driven output and termios only sends us
574   *  one character at a time.
575   */
576
577  if ( !len )
578    return 0;
579
580  /*
581   *
582   */
583#ifdef DEBUG_360
584  printk("mc68360_scc_write_support_int: char 0x%x length %d\n",
585       (unsigned int)*buf, len );
586#endif
587  /*
588   *  We must copy the data from the global memory space to MC68360 space
589   */
590
591  rtems_interrupt_disable(Irql);
592
593  scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0 );
594  memcpy((void *) ptr->txBuf, buf, len);
595  scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
596               TX_BUFFER_ADDRESS(ptr->txBuf) );
597  scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, len );
598  scc_write16( "sccTxBd->status", &ptr->sccTxBd->status,
599               (M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT) );
600
601  rtems_interrupt_enable(Irql);
602
603  return len;
604}
605
606/*
607 *  mc68360_scc_write_polled
608 *
609 *  This routine polls out the requested character.
610 */
611
612void mc68360_scc_write_polled(
613  int   minor,
614  char  cChar
615)
616{
617#ifdef DEBUG_360
618  printk("mc68360_scc_write_polled: %c\n", cChar);
619#endif
620}
621
622/*
623 *  mc68681_set_attributes
624 *
625 *  This function sets the DUART channel to reflect the requested termios
626 *  port settings.
627 */
628
629int mc68360_scc_set_attributes(
630  int minor,
631  const struct termios *t
632)
633{
634   int                    baud;
635   volatile m360_t        *m360;
636   M68360_serial_ports_t  ptr;
637
638   ptr   = Console_Port_Tbl[minor].pDeviceParams;
639   m360  = ptr->chip->m360;
640
641  baud = termios_baud_to_number(t->c_cflag & CBAUD);
642   if (baud > 0) {
643      scc_write32(
644        "pBRGC",
645        ptr->pBRGC,
646        mc68360_sccBRGC(baud, ptr->chip->m360_clock_rate)
647      );
648   }
649
650  return 0;
651}
652
653/*
654 *  mc68360_scc_close
655 *
656 *  This function shuts down the requested port.
657 */
658
659int mc68360_scc_close(
660  int      major,
661  int      minor,
662  void    *arg
663)
664{
665  return(RTEMS_SUCCESSFUL);
666}
667
668/*
669 *  mc68360_scc_inbyte_nonblocking_polled
670 *
671 *  Console Termios polling input entry point.
672 */
673
674int mc68360_scc_inbyte_nonblocking_polled(
675  int minor
676)
677{
678    return -1;
679}
680
681/*
682 *  mc68360_scc_write_support_polled
683 *
684 *  Console Termios output entry point when using polled output.
685 *
686 */
687
688int mc68360_scc_write_support_polled(
689  int         minor,
690  const char *buf,
691  int         len
692)
693{
694  printk("mc68360_scc_write_support_polled: minor %d char %c len %d\n",
695         minor, buf, len );
696  return 0;
697}
698
699/*
700 *  mc68360_scc_init
701 *
702 *  This function initializes the DUART to a quiecsent state.
703 */
704
705void mc68360_scc_init(int minor)
706{
707#ifdef DEBUG_360
708  printk("mc68360_scc_init\n");
709#endif
710}
711
712int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector )
713{
714  M68360_t   chip;
715  int        i;
716
717#ifdef DEBUG_360
718  printk("mc68360_scc_create_chip\n");
719#endif
720
721  /*
722   * Create console structure for this card
723   * XXX - Note Does this need to be moved up to if a QUICC is fitted
724   *       section?
725   */
726  if ((chip = malloc(sizeof(struct _m68360_per_chip))) == NULL)
727  {
728    printk("Error Unable to allocate memory for _m68360_per_chip\n");
729    return RTEMS_IO_ERROR;
730  }
731
732  chip->next                    = M68360_chips;
733  chip->m360                    = (void *)BoardData->baseaddr;
734  chip->m360_interrupt          = int_vector;
735  chip->m360_clock_rate         = 25000000;
736  chip->board_data              = BoardData;
737  M68360_chips                  = chip;
738
739  for (i=1; i<=4; i++) {
740    chip->port[i-1].channel     = i;
741    chip->port[i-1].chip        = chip;
742    chip->port[i-1].baud        = 9600;
743
744    switch( i ) {
745      case 1:
746        chip->port[i-1].pBRGC = &chip->m360->brgc1;
747        chip->port[i-1].pSCCB = (m360SCCparms_t *) &chip->m360->scc1p;
748        chip->port[i-1].pSCCR = &chip->m360->scc1;
749        M360SetupMemory( chip );            /* Do this first time through */
750        break;
751      case 2:
752        chip->port[i-1].pBRGC = &chip->m360->brgc2;
753        chip->port[i-1].pSCCB = &chip->m360->scc2p;
754        chip->port[i-1].pSCCR = &chip->m360->scc2;
755        break;
756      case 3:
757        chip->port[i-1].pBRGC = &chip->m360->brgc3;
758        chip->port[i-1].pSCCB = &chip->m360->scc3p;
759        chip->port[i-1].pSCCR = &chip->m360->scc3;
760        break;
761      case 4:
762        chip->port[i-1].pBRGC = &chip->m360->brgc4;
763        chip->port[i-1].pSCCB = &chip->m360->scc4p;
764        chip->port[i-1].pSCCR = &chip->m360->scc4;
765        break;
766      default:
767        printk("Invalid mc68360 channel %d\n", i);
768        return RTEMS_IO_ERROR;
769    }
770
771    /*
772     * Allocate buffer descriptors.
773     */
774
775    chip->port[i-1].sccRxBd = M360AllocateBufferDescriptors(chip, 1);
776    chip->port[i-1].sccTxBd = M360AllocateBufferDescriptors(chip, 1);
777  }
778
779  rsPMCQ1QuiccIntConnect(
780    chip->board_data->busNo,
781    chip->board_data->slotNo,
782    chip->board_data->funcNo,
783    &mc68360_sccInterruptHandler,
784    chip
785  );
786
787  return RTEMS_SUCCESSFUL;
788}
789
790console_fns mc68360_scc_fns = {
791  libchip_serial_default_probe,        /* deviceProbe */
792  mc68360_scc_open,                    /* deviceFirstOpen */
793  NULL,                                /* deviceLastClose */
794  NULL,                                /* deviceRead */
795  mc68360_scc_write_support_int,       /* deviceWrite */
796  mc68360_scc_initialize_interrupts,   /* deviceInitialize */
797  mc68360_scc_write_polled,            /* deviceWritePolled */
798  mc68360_scc_set_attributes,          /* deviceSetAttributes */
799  TRUE                                 /* deviceOutputUsesInterrupts */
800};
801
802console_fns mc68360_scc_polled = {
803  libchip_serial_default_probe,             /* deviceProbe */
804  mc68360_scc_open,                         /* deviceFirstOpen */
805  mc68360_scc_close,                        /* deviceLastClose */
806  mc68360_scc_inbyte_nonblocking_polled,    /* deviceRead */
807  mc68360_scc_write_support_polled,         /* deviceWrite */
808  mc68360_scc_init,                         /* deviceInitialize */
809  mc68360_scc_write_polled,                 /* deviceWritePolled */
810  mc68360_scc_set_attributes,               /* deviceSetAttributes */
811  FALSE                                     /* deviceOutputUsesInterrupts */
812};
813
Note: See TracBrowser for help on using the repository browser.