source: rtems/c/src/lib/libbsp/powerpc/ppcn_60x/console/config.c @ fec25de9

4.104.114.84.95
Last change on this file since fec25de9 was fec25de9, checked in by Joel Sherrill <joel.sherrill@…>, on 01/04/05 at 23:29:24

2005-01-04 Joel Sherrill <joel@…>

  • console/config.c: Remove warnings.
  • Property mode set to 100644
File size: 13.3 KB
Line 
1/*
2 *  This file contains the TTY driver table for the PPCn_60x
3 *
4 *  COPYRIGHT (c) 1998 by Radstone Technology
5 *
6 *
7 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
8 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
9 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
10 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
11 *
12 * You are hereby granted permission to use, copy, modify, and distribute
13 * this file, provided that this notice, plus the above copyright notice
14 * and disclaimer, appears in all copies. Radstone Technology will provide
15 * no support for this code.
16 *
17 *  $Id$
18 */
19
20#include <libchip/serial.h>
21#include <libchip/mc68681.h>
22#include <libchip/z85c30.h>
23#include "i8042vga.h"
24
25#include "ns16550cfg.h"
26#include "z85c30cfg.h"
27
28#include <pci.h>
29
30#define PMX1553_BUS     2
31#define PMX1553_SLOT    1
32
33/*
34 *  Based on BSP configuration information decide whether to do polling IO
35 *  or interrupt driven IO.
36 */
37
38#if (CONSOLE_USE_INTERRUPTS)
39#define NS16550_FUNCTIONS &ns16550_fns
40#define Z85C30_FUNCTIONS  &z85c30_fns
41#else
42#define NS16550_FUNCTIONS &ns16550_fns_polled
43#define Z85C30_FUNCTIONS  &z85c30_fns_polled
44#endif
45
46/*
47 * Configuration specific probe routines
48 */
49static boolean config_PMX1553_probe(int minor);
50static boolean config_z85c30_probe(int minor);
51
52/*
53 * The following table configures the console drivers used in this BSP.
54 *
55 * The first entry which, when probed, is available, will be named /dev/console,
56 * all others being given the name indicated.
57 *
58 * Each field is interpreted thus:
59 *
60 * sDeviceName  This is the name of the device.
61 * pDeviceFns   This is a pointer to the set of driver routines to use.
62 * pDeviceFlow  This is a pointer to the set of flow control routines to
63 *              use. Serial device drivers will typically supply RTSCTS
64 *              and DTRCTS handshake routines for DCE to DCE communication,
65 *              however for DCE to DTE communication, no such routines
66 *              should be necessary as RTS will be driven automatically
67 *              when the transmitter is active.
68 * ulMargin     The high water mark in the input buffer is set to the buffer
69 *              size less ulMargin. Once this level is reached, the driver's
70 *              flow control routine used to stop the remote transmitter will
71 *              be called. This figure should be greater than or equal to
72 *              the number of stages of FIFO between the transmitter and
73 *              receiver.
74 * ulHysteresis After the high water mark specified by ulMargin has been
75 *              reached, the driver's routine to re-start the remote
76 *              transmitter will be called once the level in the input
77 *              buffer has fallen by ulHysteresis bytes.
78 * pDeviceParams This contains either device specific data or a pointer to a
79 *              device specific structure containing additional information
80 *              not provided in this table.
81 * ulCtrlPort1  This is the primary control port number for the device. This
82 *              may be used to specify different instances of the same device
83 *              type.
84 * ulCtrlPort2  This is the secondary control port number, of use when a given
85 *              device has more than one available channel.
86 * ulDataPort   This is the port number for the data port of the device
87 * ulIntVector  This encodes the interrupt vector of the device.
88 *
89 */
90console_tbl     Console_Port_Tbl[] = {
91        {
92                "/dev/vga",                     /* sDeviceName */
93                SERIAL_CUSTOM,                  /* deviceType */
94                &i8042vga_fns,                  /* pDeviceFns */
95                NULL,                           /* deviceProbe */
96                NULL,                           /* pDeviceFlow */
97                0,                              /* ulMargin */
98                0,                              /* ulHysteresis */
99                (void *)0,                      /* pDeviceParams */
100                I8042_CS,                       /* ulCtrlPort1 */
101                0,                              /* ulCtrlPort2 */
102                I8042_DATA,                     /* ulDataPort */
103                Read_ns16550_register,          /* getRegister */
104                Write_ns16550_register,         /* setRegister */
105                NULL,                           /* getData */
106                NULL,                           /* setData */
107                0,                              /* ulClock */
108                PPCN_60X_IRQ_KBD                /* ulIntVector */
109        },
110        {
111                "/dev/com1",                    /* sDeviceName */
112                SERIAL_NS16550,                 /* deviceType */
113                NS16550_FUNCTIONS,              /* pDeviceFns */
114                NULL,                           /* deviceProbe */
115                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
116                16,                             /* ulMargin */
117                8,                              /* ulHysteresis */
118                (void *)9600,   /* baud rate */ /* pDeviceParams */
119                NS16550_PORT_A,                 /* ulCtrlPort1 */
120                0,                              /* ulCtrlPort2 */
121                NS16550_PORT_A,                 /* ulDataPort */
122                Read_ns16550_register,          /* getRegister */
123                Write_ns16550_register,         /* setRegister */
124                NULL,                           /* getData */
125                NULL,                           /* setData */
126                0,                              /* ulClock */
127                PPCN_60X_IRQ_COM1               /* ulIntVector */
128        },
129        {
130                "/dev/ser1",                    /* sDeviceName */
131                SERIAL_NS16550,                 /* deviceType */
132                NS16550_FUNCTIONS,              /* pDeviceFns */
133                config_PMX1553_probe,           /* deviceProbe */
134                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
135                80,                             /* ulMargin */
136                8,                              /* ulHysteresis */
137                (void *)9600,   /* baud rate */ /* pDeviceParams */
138                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
139                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
140                1,      /* Channel 1-4 */       /* ulDataPort */
141                NULL,                           /* getRegister */
142                NULL,                           /* setRegister */
143                NULL,                           /* getData */
144                NULL,                           /* setData */
145                0,                              /* ulClock */
146                0       /* RS232 */             /* ulIntVector */
147        },
148        {
149                "/dev/ser2",                    /* sDeviceName */
150                SERIAL_NS16550,                 /* deviceType */
151                NS16550_FUNCTIONS,              /* pDeviceFns */
152                config_PMX1553_probe,           /* deviceProbe */
153                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
154                80,                             /* ulMargin */
155                8,                              /* ulHysteresis */
156                (void *)9600,   /* baud rate */ /* pDeviceParams */
157                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
158                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
159                2,      /* Channel 1-4 */       /* ulDataPort */
160                Read_ns16550_register,          /* getRegister */
161                Write_ns16550_register,         /* setRegister */
162                NULL,                           /* getData */
163                NULL,                           /* setData */
164                0,                              /* ulClock */
165                0       /* RS232 */             /* ulIntVector */
166        },
167        {
168                "/dev/ser3",                    /* sDeviceName */
169                SERIAL_NS16550,                 /* deviceType */
170                NS16550_FUNCTIONS,              /* pDeviceFns */
171                config_PMX1553_probe,           /* deviceProbe */
172                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
173                96,                             /* ulMargin */
174                8,                              /* ulHysteresis */
175                (void *)57600,  /* baud rate */ /* pDeviceParams */
176                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
177                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
178                3,      /* Channel 1-4 */       /* ulDataPort */
179                Read_ns16550_register,          /* getRegister */
180                Write_ns16550_register,         /* setRegister */
181                NULL,                           /* getData */
182                NULL,                           /* setData */
183                0,                              /* ulClock */
184                0       /* RS232 */             /* ulIntVector */
185        },
186        {
187                "/dev/ser4",                    /* sDeviceName */
188                SERIAL_NS16550,                 /* deviceType */
189                NS16550_FUNCTIONS,              /* pDeviceFns */
190                config_PMX1553_probe,           /* deviceProbe */
191                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
192                96,                             /* ulMargin */
193                8,                              /* ulHysteresis */
194                (void *)57600,  /* baud rate */ /* pDeviceParams */
195                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
196                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
197                4,      /* Channel 1-4 */       /* ulDataPort */
198                Read_ns16550_register,          /* getRegister */
199                Write_ns16550_register,         /* setRegister */
200                NULL,                           /* getData */
201                NULL,                           /* setData */
202                0,                              /* ulClock */
203                0       /* RS232 */             /* ulIntVector */
204        },
205#if !PPCN_60X_USE_DINK
206        {
207                "/dev/com2",                    /* sDeviceName */
208                SERIAL_NS16550,                 /* deviceType */
209                NS16550_FUNCTIONS,              /* pDeviceFns */
210                NULL,                           /* deviceProbe */
211                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
212                16,                             /* ulMargin */
213                8,                              /* ulHysteresis */
214                (void *)9600,   /* baud rate */ /* pDeviceParams */
215                NS16550_PORT_B,                 /* ulCtrlPort1 */
216                0,                              /* ulCtrlPort2 */
217                NS16550_PORT_B,                 /* ulDataPort */
218                Read_ns16550_register,          /* getRegister */
219                Write_ns16550_register,         /* setRegister */
220                NULL,                           /* getData */
221                NULL,                           /* setData */
222                0,                              /* ulClock */
223                PPCN_60X_IRQ_COM2               /* ulIntVector */
224        },
225#endif
226        {
227                "/dev/com3",                    /* sDeviceName */
228                SERIAL_Z85C30,                  /* deviceType */
229                Z85C30_FUNCTIONS,               /* pDeviceFns */
230                config_z85c30_probe,            /* deviceProbe */
231                &z85c30_flow_RTSCTS,            /* pDeviceFlow */
232                16,                             /* ulMargin */
233                8,                              /* ulHysteresis */
234                (void *)9600,   /* baud rate */ /* pDeviceParams */
235                Z85C30_CTRL_A,                  /* ulCtrlPort1 */
236                Z85C30_CTRL_A,                  /* ulCtrlPort2 */
237                Z85C30_DATA_A,                  /* ulDataPort */
238                Read_85c30_register,            /* getRegister */
239                Write_85c30_register,           /* setRegister */
240                Read_85c30_data,                /* getData */
241                Write_85c30_data,               /* setData */
242                0,                              /* ulClock */
243                PPCN_60X_IRQ_COM3_4             /* ulIntVector */
244        },
245        {
246                "/dev/com4",                    /* sDeviceName */
247                SERIAL_Z85C30,                  /* deviceType */
248                Z85C30_FUNCTIONS,               /* pDeviceFns */
249                config_z85c30_probe,            /* deviceProbe */
250                &z85c30_flow_RTSCTS,            /* pDeviceFlow */
251                16,                             /* ulMargin */
252                8,                              /* ulHysteresis */
253                (void *)9600,   /* baud rate */ /* pDeviceParams */
254                Z85C30_CTRL_B,                  /* ulCtrlPort1 */
255                Z85C30_CTRL_A,                  /* ulCtrlPort2 */
256                Z85C30_DATA_B,                  /* ulDataPort */
257                Read_85c30_register,            /* getRegister */
258                Write_85c30_register,           /* setRegister */
259                Read_85c30_data,                /* getData */
260                Write_85c30_data,               /* setData */
261                0,                              /* ulClock */
262                PPCN_60X_IRQ_COM3_4             /* ulIntVector */
263        }
264};
265
266/*
267 * Define serial port write registers structure.
268 */
269typedef volatile struct _SP_WRITE_REGISTERS {
270    unsigned char TransmitBuffer;
271    unsigned char InterruptEnable;
272    unsigned char FifoControl;
273    unsigned char LineControl;
274    unsigned char ModemControl;
275    unsigned char Reserved1;
276    unsigned char ModemStatus;
277    unsigned char ScratchPad;
278} SP_WRITE_REGISTERS, *PSP_WRITE_REGISTERS;
279
280static boolean config_PMX1553_probe(int minor)
281{
282        uint8_t   ucBusNumber, ucSlotNumber, ucChannel;
283        uint8_t   ucIntLine;
284        uint32_t   ulPortBase, ulMemBase, ulDeviceID, ulTemp;
285        uint8_t   *pucSIO_cir, *pucUart_int_sr, *pucUartDevIntReg;
286        PSP_WRITE_REGISTERS     pNS16550Write;
287
288        /*
289         * Extract PCI bus/slot and channel number
290         */
291        ucBusNumber=Console_Port_Tbl[minor].ulCtrlPort1;
292        ucSlotNumber=Console_Port_Tbl[minor].ulCtrlPort2;
293        ucChannel=Console_Port_Tbl[minor].ulDataPort;
294
295        PCIConfigRead32(ucBusNumber,
296                        ucSlotNumber,
297                        0,
298                        PCI_CONFIG_VENDOR_LOW,
299                        &ulDeviceID);
300
301        if(ulDeviceID!=0x000111b5)
302        {
303                return FALSE;
304        }
305
306        /*
307         * At this point we know we have a PMC1553 or PMX1553 card
308         *
309         * Check for PMX1553 uart legacy IO ports
310         */
311        PCIConfigRead32(ucBusNumber,
312                        ucSlotNumber,
313                        0,
314                        PCI_CONFIG_BAR_3,
315                        &ulPortBase);
316
317        if(ulPortBase==0)
318        {
319                /*
320                 * This is either a PMC1553 or we can't see the uart
321                 * registers
322                 */
323                return FALSE;
324        }
325
326        PCIConfigRead32(ucBusNumber,
327                        ucSlotNumber,
328                        0,
329                        PCI_CONFIG_BAR_2,
330                        &ulMemBase);
331
332        pucUartDevIntReg=(uint8_t*)(PCI_MEM_BASE+ulMemBase);
333        pucUart_int_sr=(uint8_t*)(PCI_MEM_BASE+ulMemBase+0x10);
334        pucSIO_cir=(uint8_t*)(PCI_MEM_BASE+ulMemBase+0x18);
335
336        /*
337         * Use ulIntVector field to select RS232/RS422
338         */
339        if(Console_Port_Tbl[minor].ulIntVector==0)
340        {
341                /*
342                 * Select RS232 mode
343                 */
344                *pucSIO_cir&=~(1<<(ucChannel-1));
345        }
346        else
347        {
348                /*
349                 * Select RS422 mode
350                 */
351                *pucSIO_cir|=1<<(ucChannel-1);
352        }
353        EIEIO;
354        /*
355         * Bring device out of reset
356         */
357        *pucSIO_cir&=0xbf;
358        EIEIO;
359        /*
360         * Enable all channels as active
361         */
362        *pucSIO_cir|=0x10;
363        EIEIO;
364        *pucSIO_cir&=0xdf;
365
366        PCIConfigRead8(ucBusNumber,
367                       ucSlotNumber,
368                       0,
369                       PCI_CONFIG_INTERRUPTLINE,
370                       &ucIntLine);
371
372        ulPortBase&=~PCI_ADDRESS_IO_SPACE;
373
374        ulPortBase+=8*(ucChannel-1);
375
376        Console_Port_Tbl[minor].ulCtrlPort1=
377        Console_Port_Tbl[minor].ulDataPort=ulPortBase;
378        if(Console_Port_Tbl[minor].pDeviceFns!=&ns16550_fns_polled)
379        {
380                Console_Port_Tbl[minor].ulIntVector=PPCN_60X_IRQ_PCI(ucIntLine);
381
382                /*
383                 * Enable interrupt
384                 */
385                *pucUart_int_sr=(~*pucUart_int_sr)&(0x08<<ucChannel);
386
387                /*
388                 * Enable interrupt to PCI
389                 */
390                *pucUartDevIntReg=(~*pucUartDevIntReg)&0x80;
391        }
392        else
393        {
394                /*
395                 * Disable interrupt
396                 */
397                *pucUart_int_sr&=(0x08<<ucChannel);
398        }
399
400        /*
401         * Enable Auto CTS to facilitate flow control
402         */
403        pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
404        /*
405         * Enable special register set and unlock Enhanced Feature Register
406         */
407        outport_byte(&pNS16550Write->LineControl, 0xbf);
408        /*
409         * Unlock enhanced function bits
410         */
411        outport_byte(&pNS16550Write->FifoControl, 0x10);
412        /*
413         * Disable special register set and lock Enhanced Feature Register
414         */
415        outport_byte(&pNS16550Write->LineControl, 0);
416        /*
417         * Select div 1
418         */
419        outport_byte(&pNS16550Write->ModemControl, 0x00);
420        /*
421         * Enable special register set and unlock Enhanced Feature Register
422         */
423        outport_byte(&pNS16550Write->LineControl, 0xbf);
424        /*
425         * Lock enhanced function bits and enable auto CTS
426         */
427        outport_byte(&pNS16550Write->FifoControl, 0x80);
428        /*
429         * Disable special register set and lock Enhanced Feature Register
430         */
431        outport_byte(&pNS16550Write->LineControl, 0);
432
433        /*
434         * The PMX1553 currently uses a 16 MHz clock rather than the
435         * 7.3728 MHz clock described in the ST16C654 data sheet. When
436         * available, 22.1184 MHz will be used allowing rates up to
437         * 1382400 baud (RS422 only).
438         */
439
440        ulTemp = (uint32_t)Console_Port_Tbl[minor].pDeviceParams
441#if 1
442        /*
443         * Scale requested baud rate for 16 MHz clock
444         */
445        ulTemp *= 7373;
446        ulTemp /= 16000;
447#else
448        /*
449         * Scale requested baud rate for 22.1184 MHz clock
450         */
451        ulTemp /= 3;
452#endif
453
454        /*
455         * In order to maintain maximum data rate accuracy, we will
456         * apply a div 4 here rather than in hardware (using MCR bit 7).
457         */
458        ultemp /= 4;
459
460        Console_Port_Tbl[minor].pDeviceParams = (void *)ulTemp;
461
462        return(TRUE);
463}
464
465static boolean config_z85c30_probe(int minor)
466{
467        /*
468         * PPC1 and PPC1a do not have this device
469         */
470        if((ucSystemType==SYS_TYPE_PPC1) ||
471           (ucSystemType==SYS_TYPE_PPC1a))
472        {
473                return (FALSE);
474        }
475
476        /*
477         * All other boards supported by this BSP have the z85c30 device
478         */
479
480        /*
481         * Ensure that CIO port B is configured for
482         * default driver enable
483         */
484        outport_byte(0x861, 0x33);
485
486        return(TRUE);
487}
Note: See TracBrowser for help on using the repository browser.