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

4.104.114.84.95
Last change on this file since 5c609dd was 5c609dd, checked in by Joel Sherrill <joel.sherrill@…>, on 02/18/99 at 19:18:28

Missed this file in the merge.

  • Property mode set to 100644
File size: 11.1 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 "i8042vga.h"
21#include "ns16550.h"
22#include "z85c30.h"
23
24#include <pci.h>
25
26#define PMX1553_BUS     2
27#define PMX1553_SLOT    1
28
29/*
30 * Configuration specific probe routines
31 */
32static boolean config_PMX1553_probe(int minor);
33static boolean config_z85c30_probe(int minor);
34
35/*
36 * The following table configures the console drivers used in this BSP.
37 *
38 * The first entry which, when probed, is available, will be named /dev/console,
39 * all others being given the name indicated.
40 *
41 * Each field is interpreted thus:
42 *
43 * sDeviceName  This is the name of the device.
44 * pDeviceFns   This is a pointer to the set of driver routines to use.
45 * pDeviceFlow  This is a pointer to the set of flow control routines to
46 *              use. Serial device drivers will typically supply RTSCTS
47 *              and DTRCTS handshake routines for DCE to DCE communication,
48 *              however for DCE to DTE communication, no such routines
49 *              should be necessary as RTS will be driven automatically
50 *              when the transmitter is active.
51 * ulMargin     The high water mark in the input buffer is set to the buffer
52 *              size less ulMargin. Once this level is reached, the driver's
53 *              flow control routine used to stop the remote transmitter will
54 *              be called. This figure should be greater than or equal to
55 *              the number of stages of FIFO between the transmitter and
56 *              receiver.
57 * ulHysteresis After the high water mark specified by ulMargin has been
58 *              reached, the driver's routine to re-start the remote
59 *              transmitter will be called once the level in the input
60 *              buffer has fallen by ulHysteresis bytes.
61 * pDeviceParams This contains either device specific data or a pointer to a
62 *              device specific structure containing additional information
63 *              not provided in this table.
64 * ulCtrlPort1  This is the primary control port number for the device. This
65 *              may be used to specify different instances of the same device
66 *              type.
67 * ulCtrlPort2  This is the secondary control port number, of use when a given
68 *              device has more than one available channel.
69 * ulDataPort   This is the port number for the data port of the device
70 * ulIntVector  This encodes the interrupt vector of the device.
71 *
72 */
73console_tbl     Console_Port_Tbl[] = {
74        {
75                "/dev/vga",                     /* sDeviceName */
76                &i8042vga_fns,                  /* pDeviceFns */
77                NULL,                           /* deviceProbe */
78                NULL,                           /* pDeviceFlow */
79                0,                              /* ulMargin */
80                0,                              /* ulHysteresis */
81                (void *)0,                      /* pDeviceParams */
82                I8042_CS,                       /* ulCtrlPort1 */
83                0,                              /* ulCtrlPort2 */
84                I8042_DATA,                     /* ulDataPort */
85                PPCN_60X_IRQ_KBD                /* ulIntVector */
86        },
87        {
88                "/dev/com1",                    /* sDeviceName */
89                &ns16550_fns,                   /* pDeviceFns */
90                NULL,                           /* deviceProbe */
91                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
92                16,                             /* ulMargin */
93                8,                              /* ulHysteresis */
94                (void *)9600,   /* baud rate */ /* pDeviceParams */
95                NS16550_PORT_A,                 /* ulCtrlPort1 */
96                0,                              /* ulCtrlPort2 */
97                NS16550_PORT_A,                 /* ulDataPort */
98                PPCN_60X_IRQ_COM1               /* ulIntVector */
99        },
100        {
101                "/dev/ser1",                    /* sDeviceName */
102                &ns16550_fns,                   /* pDeviceFns */
103                config_PMX1553_probe,           /* deviceProbe */
104                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
105                80,                             /* ulMargin */
106                8,                              /* ulHysteresis */
107                (void *)9600,   /* baud rate */ /* pDeviceParams */
108                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
109                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
110                1,      /* Channel 1-4 */       /* ulDataPort */
111                0       /* RS232 */             /* ulIntVector */
112        },
113        {
114                "/dev/ser2",                    /* sDeviceName */
115                &ns16550_fns,                   /* pDeviceFns */
116                config_PMX1553_probe,           /* deviceProbe */
117                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
118                80,                             /* ulMargin */
119                8,                              /* ulHysteresis */
120                (void *)9600,   /* baud rate */ /* pDeviceParams */
121                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
122                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
123                2,      /* Channel 1-4 */       /* ulDataPort */
124                0       /* RS232 */             /* ulIntVector */
125        },
126        {
127                "/dev/ser3",                    /* sDeviceName */
128                &ns16550_fns,                   /* pDeviceFns */
129                config_PMX1553_probe,           /* deviceProbe */
130                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
131                96,                             /* ulMargin */
132                8,                              /* ulHysteresis */
133                (void *)57600,  /* baud rate */ /* pDeviceParams */
134                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
135                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
136                3,      /* Channel 1-4 */       /* ulDataPort */
137                0       /* RS232 */             /* ulIntVector */
138        },
139        {
140                "/dev/ser4",                    /* sDeviceName */
141                &ns16550_fns,                   /* pDeviceFns */
142                config_PMX1553_probe,           /* deviceProbe */
143                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
144                96,                             /* ulMargin */
145                8,                              /* ulHysteresis */
146                (void *)57600,  /* baud rate */ /* pDeviceParams */
147                PMX1553_BUS,    /* PCI bus */   /* ulCtrlPort1 */
148                PMX1553_SLOT,   /* PCI slot */  /* ulCtrlPort2 */
149                4,      /* Channel 1-4 */       /* ulDataPort */
150                0       /* RS232 */             /* ulIntVector */
151        },
152#if !PPCN_60X_USE_DINK
153        {
154                "/dev/com2",                    /* sDeviceName */
155                &ns16550_fns,                   /* pDeviceFns */
156                NULL,                           /* deviceProbe */
157                &ns16550_flow_RTSCTS,           /* pDeviceFlow */
158                16,                             /* ulMargin */
159                8,                              /* ulHysteresis */
160                (void *)9600,   /* baud rate */ /* pDeviceParams */
161                NS16550_PORT_B,                 /* ulCtrlPort1 */
162                0,                              /* ulCtrlPort2 */
163                NS16550_PORT_B,                 /* ulDataPort */
164                PPCN_60X_IRQ_COM2               /* ulIntVector */
165        },
166#endif
167        {
168                "/dev/com3",                    /* sDeviceName */
169                &z85c30_fns,                    /* pDeviceFns */
170                config_z85c30_probe,            /* deviceProbe */
171                &z85c30_flow_RTSCTS,            /* pDeviceFlow */
172                16,                             /* ulMargin */
173                8,                              /* ulHysteresis */
174                (void *)9600,   /* baud rate */ /* pDeviceParams */
175                Z85C30_CTRL_A,                  /* ulCtrlPort1 */
176                Z85C30_CTRL_A,                  /* ulCtrlPort2 */
177                Z85C30_DATA_A,                  /* ulDataPort */
178                PPCN_60X_IRQ_COM3_4             /* ulIntVector */
179        },
180        {
181                "/dev/com4",                    /* sDeviceName */
182                &z85c30_fns,                    /* pDeviceFns */
183                config_z85c30_probe,            /* deviceProbe */
184                &z85c30_flow_RTSCTS,            /* pDeviceFlow */
185                16,                             /* ulMargin */
186                8,                              /* ulHysteresis */
187                (void *)9600,   /* baud rate */ /* pDeviceParams */
188                Z85C30_CTRL_B,                  /* ulCtrlPort1 */
189                Z85C30_CTRL_A,                  /* ulCtrlPort2 */
190                Z85C30_DATA_B,                  /* ulDataPort */
191                PPCN_60X_IRQ_COM3_4             /* ulIntVector */
192        }
193};
194
195/*
196 * Define serial port write registers structure.
197 */
198typedef volatile struct _SP_WRITE_REGISTERS {
199    unsigned char TransmitBuffer;
200    unsigned char InterruptEnable;
201    unsigned char FifoControl;
202    unsigned char LineControl;
203    unsigned char ModemControl;
204    unsigned char Reserved1;
205    unsigned char ModemStatus;
206    unsigned char ScratchPad;
207} SP_WRITE_REGISTERS, *PSP_WRITE_REGISTERS;
208
209static boolean config_PMX1553_probe(int minor)
210{
211        unsigned8 ucBusNumber, ucSlotNumber, ucChannel;
212        unsigned8 ucIntLine;
213        unsigned32 ulPortBase, ulMemBase, ulDeviceID;
214        unsigned8 *pucSIO_cir, *pucUart_int_sr, *pucUartDevIntReg;
215        PSP_WRITE_REGISTERS     pNS16550Write;
216
217        /*
218         * Extract PCI bus/slot and channel number
219         */
220        ucBusNumber=Console_Port_Tbl[minor].ulCtrlPort1;
221        ucSlotNumber=Console_Port_Tbl[minor].ulCtrlPort2;
222        ucChannel=Console_Port_Tbl[minor].ulDataPort;
223
224        PCIConfigRead32(ucBusNumber,
225                        ucSlotNumber,
226                        0,
227                        PCI_CONFIG_VENDOR_LOW,
228                        &ulDeviceID);
229
230        if(ulDeviceID!=0x000111b5)
231        {
232                return FALSE;
233        }
234
235        /*
236         * At this point we know we have a PMC1553 or PMX1553 card
237         *
238         * Check for PMX1553 uart legacy IO ports
239         */
240        PCIConfigRead32(ucBusNumber,
241                        ucSlotNumber,
242                        0,
243                        PCI_CONFIG_BAR_3,
244                        &ulPortBase);
245
246        if(ulPortBase==0)
247        {
248                /*
249                 * This is either a PMC1553 or we can't see the uart
250                 * registers
251                 */
252                return FALSE;
253        }
254
255        PCIConfigRead32(ucBusNumber,
256                        ucSlotNumber,
257                        0,
258                        PCI_CONFIG_BAR_2,
259                        &ulMemBase);
260
261        pucUartDevIntReg=(unsigned8 *)(PCI_MEM_BASE+ulMemBase);
262        pucUart_int_sr=(unsigned8 *)(PCI_MEM_BASE+ulMemBase+0x10);
263        pucSIO_cir=(unsigned8 *)(PCI_MEM_BASE+ulMemBase+0x18);
264
265        /*
266         * Use ulIntVector field to select RS232/RS422
267         */
268        if(Console_Port_Tbl[minor].ulIntVector==0)
269        {
270                /*
271                 * Select RS232 mode
272                 */
273                *pucSIO_cir&=~(1<<(ucChannel-1));
274        }
275        else
276        {
277                /*
278                 * Select RS422 mode
279                 */
280                *pucSIO_cir|=1<<(ucChannel-1);
281        }
282        EIEIO;
283        /*
284         * Bring device out of reset
285         */
286        *pucSIO_cir&=0xbf;
287        EIEIO;
288        /*
289         * Enable all channels as active
290         */
291        *pucSIO_cir|=0x10;
292        EIEIO;
293        *pucSIO_cir&=0xdf;
294
295        PCIConfigRead8(ucBusNumber,
296                       ucSlotNumber,
297                       0,
298                       PCI_CONFIG_INTERRUPTLINE,
299                       &ucIntLine);
300
301        ulPortBase&=~PCI_ADDRESS_IO_SPACE;
302
303        ulPortBase+=8*(ucChannel-1);
304
305        Console_Port_Tbl[minor].ulCtrlPort1=
306        Console_Port_Tbl[minor].ulDataPort=ulPortBase;
307        if(Console_Port_Tbl[minor].pDeviceFns!=&ns16550_fns_polled)
308        {
309                Console_Port_Tbl[minor].ulIntVector=PPCN_60X_IRQ_PCI(ucIntLine);
310
311                /*
312                 * Enable interrupt
313                 */
314                *pucUart_int_sr=(~*pucUart_int_sr)&(0x08<<ucChannel);
315
316                /*
317                 * Enable interrupt to PCI
318                 */
319                *pucUartDevIntReg=(~*pucUartDevIntReg)&0x80;
320        }
321        else
322        {
323                /*
324                 * Disable interrupt
325                 */
326                *pucUart_int_sr&=(0x08<<ucChannel);
327        }
328
329        /*
330         * Enable Auto CTS to facilitate flow control
331         */
332        pNS16550Write=(PSP_WRITE_REGISTERS)Console_Port_Tbl[minor].ulCtrlPort1;
333        /*
334         * Enable special register set and unlock Enhanced Feature Register
335         */
336        outport_byte(&pNS16550Write->LineControl, 0xbf);
337        /*
338         * Unlock enhanced function bits
339         */
340        outport_byte(&pNS16550Write->FifoControl, 0x10);
341        /*
342         * Disable special register set and lock Enhanced Feature Register
343         */
344        outport_byte(&pNS16550Write->LineControl, 0);
345        /*
346         * Select div 1
347         */
348        outport_byte(&pNS16550Write->ModemControl, 0x00);
349        /*
350         * Enable special register set and unlock Enhanced Feature Register
351         */
352        outport_byte(&pNS16550Write->LineControl, 0xbf);
353        /*
354         * Lock enhanced function bits and enable auto CTS
355         */
356        outport_byte(&pNS16550Write->FifoControl, 0x80);
357        /*
358         * Disable special register set and lock Enhanced Feature Register
359         */
360        outport_byte(&pNS16550Write->LineControl, 0);
361       
362        /*
363         * The PMX1553 currently uses a 16 MHz clock rather than the
364         * 7.3728 MHz clock described in the ST16C654 data sheet. When
365         * available, 22.1184 MHz will be used allowing rates up to
366         * 1382400 baud (RS422 only).
367         */
368#if 1
369        /*
370         * Scale requested baud rate for 16 MHz clock
371         */
372        (unsigned32)Console_Port_Tbl[minor].pDeviceParams*=7373;
373        (unsigned32)Console_Port_Tbl[minor].pDeviceParams/=16000;
374#else
375        /*
376         * Scale requested baud rate for 22.1184 MHz clock
377         */
378        (unsigned32)Console_Port_Tbl[minor].pDeviceParams/=3;
379#endif
380        /*
381         * In order to maintain maximum data rate accuracy, we will
382         * apply a div 4 here rather than in hardware (using MCR bit 7).
383         */
384        (unsigned32)Console_Port_Tbl[minor].pDeviceParams/=4;
385
386        return(TRUE);
387}
388
389static boolean config_z85c30_probe(int minor)
390{
391        /*
392         * PPC1 and PPC1a do not have this device
393         */
394        if((ucSystemType==SYS_TYPE_PPC1) ||
395           (ucSystemType==SYS_TYPE_PPC1a))
396        {
397                return (FALSE);
398        }
399
400        /*
401         * All other boards supported by this BSP have the z85c30 device
402         */
403
404        /*
405         * Ensure that CIO port B is configured for
406         * default driver enable
407         */
408        outport_byte(0x861, 0x33);
409
410        return(TRUE);
411}
412
Note: See TracBrowser for help on using the repository browser.