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

4.104.114.84.9
Last change on this file since 0329aae was 0329aae, checked in by Jennifer Averett <Jennifer.Averett@…>, on Apr 28, 2005 at 2:05:14 PM

2005-04-28 Jennifer Averett <jennifer.averett@…>

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