2005-04-16 15:20:36 -07:00
/*
* Copyright 2003 PMC - Sierra
* Author : Manish Lachwani ( lachwani @ pmc - sierra . com )
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*
* THIS SOFTWARE IS PROVIDED ` ` AS IS ' ' AND ANY EXPRESS OR IMPLIED
* WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF
* USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
* Support for KGDB for the Yosemite board . We make use of single serial
* port to be used for KGDB as well as console . The second serial port
* seems to be having a problem . Single IRQ is allocated for both the
* ports . Hence , the interrupt routing code needs to figure out whether
* the interrupt came from channel A or B .
*/
# include <asm/serial.h>
/*
* Baud rate , Parity , Data and Stop bit settings for the
* serial port on the Yosemite . Note that the Early printk
* patch has been added . So , we should be all set to go
*/
# define YOSEMITE_BAUD_2400 2400
# define YOSEMITE_BAUD_4800 4800
# define YOSEMITE_BAUD_9600 9600
# define YOSEMITE_BAUD_19200 19200
# define YOSEMITE_BAUD_38400 38400
# define YOSEMITE_BAUD_57600 57600
# define YOSEMITE_BAUD_115200 115200
# define YOSEMITE_PARITY_NONE 0
# define YOSEMITE_PARITY_ODD 0x08
# define YOSEMITE_PARITY_EVEN 0x18
# define YOSEMITE_PARITY_MARK 0x28
# define YOSEMITE_PARITY_SPACE 0x38
# define YOSEMITE_DATA_5BIT 0x0
# define YOSEMITE_DATA_6BIT 0x1
# define YOSEMITE_DATA_7BIT 0x2
# define YOSEMITE_DATA_8BIT 0x3
# define YOSEMITE_STOP_1BIT 0x0
# define YOSEMITE_STOP_2BIT 0x4
/* This is crucial */
# define SERIAL_REG_OFS 0x1
# define SERIAL_RCV_BUFFER 0x0
# define SERIAL_TRANS_HOLD 0x0
# define SERIAL_SEND_BUFFER 0x0
# define SERIAL_INTR_ENABLE (1 * SERIAL_REG_OFS)
# define SERIAL_INTR_ID (2 * SERIAL_REG_OFS)
# define SERIAL_DATA_FORMAT (3 * SERIAL_REG_OFS)
# define SERIAL_LINE_CONTROL (3 * SERIAL_REG_OFS)
# define SERIAL_MODEM_CONTROL (4 * SERIAL_REG_OFS)
# define SERIAL_RS232_OUTPUT (4 * SERIAL_REG_OFS)
# define SERIAL_LINE_STATUS (5 * SERIAL_REG_OFS)
# define SERIAL_MODEM_STATUS (6 * SERIAL_REG_OFS)
# define SERIAL_RS232_INPUT (6 * SERIAL_REG_OFS)
# define SERIAL_SCRATCH_PAD (7 * SERIAL_REG_OFS)
# define SERIAL_DIVISOR_LSB (0 * SERIAL_REG_OFS)
# define SERIAL_DIVISOR_MSB (1 * SERIAL_REG_OFS)
/*
* Functions to READ and WRITE to serial port 0
*/
# define SERIAL_READ(ofs) (*((volatile unsigned char*) \
( TITAN_SERIAL_BASE + ofs ) ) )
# define SERIAL_WRITE(ofs, val) ((*((volatile unsigned char*) \
( TITAN_SERIAL_BASE + ofs ) ) ) = val )
/*
* Functions to READ and WRITE to serial port 1
*/
# define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \
2007-02-06 16:43:31 +00:00
( TITAN_SERIAL_BASE_1 + ofs ) ) )
2005-04-16 15:20:36 -07:00
# define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \
( TITAN_SERIAL_BASE_1 + ofs ) ) ) = val )
/*
* Second serial port initialization
*/
void init_second_port ( void )
{
/* Disable Interrupts */
SERIAL_WRITE_1 ( SERIAL_LINE_CONTROL , 0x0 ) ;
SERIAL_WRITE_1 ( SERIAL_INTR_ENABLE , 0x0 ) ;
{
unsigned int divisor ;
SERIAL_WRITE_1 ( SERIAL_LINE_CONTROL , 0x80 ) ;
divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200 ;
SERIAL_WRITE_1 ( SERIAL_DIVISOR_LSB , divisor & 0xff ) ;
SERIAL_WRITE_1 ( SERIAL_DIVISOR_MSB ,
( divisor & 0xff00 ) > > 8 ) ;
SERIAL_WRITE_1 ( SERIAL_LINE_CONTROL , 0x0 ) ;
}
SERIAL_WRITE_1 ( SERIAL_DATA_FORMAT , YOSEMITE_DATA_8BIT |
YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT ) ;
/* Enable Interrupts */
SERIAL_WRITE_1 ( SERIAL_INTR_ENABLE , 0xf ) ;
}
/* Initialize the serial port for KGDB debugging */
void debugInit ( unsigned int baud , unsigned char data , unsigned char parity ,
unsigned char stop )
{
/* Disable Interrupts */
SERIAL_WRITE ( SERIAL_LINE_CONTROL , 0x0 ) ;
SERIAL_WRITE ( SERIAL_INTR_ENABLE , 0x0 ) ;
{
unsigned int divisor ;
SERIAL_WRITE ( SERIAL_LINE_CONTROL , 0x80 ) ;
divisor = TITAN_SERIAL_BASE_BAUD / baud ;
SERIAL_WRITE ( SERIAL_DIVISOR_LSB , divisor & 0xff ) ;
SERIAL_WRITE ( SERIAL_DIVISOR_MSB , ( divisor & 0xff00 ) > > 8 ) ;
SERIAL_WRITE ( SERIAL_LINE_CONTROL , 0x0 ) ;
}
SERIAL_WRITE ( SERIAL_DATA_FORMAT , data | parity | stop ) ;
}
static int remoteDebugInitialized = 0 ;
unsigned char getDebugChar ( void )
{
if ( ! remoteDebugInitialized ) {
remoteDebugInitialized = 1 ;
debugInit ( YOSEMITE_BAUD_115200 ,
YOSEMITE_DATA_8BIT ,
YOSEMITE_PARITY_NONE , YOSEMITE_STOP_1BIT ) ;
}
while ( ( SERIAL_READ ( SERIAL_LINE_STATUS ) & 0x1 ) = = 0 ) ;
return SERIAL_READ ( SERIAL_RCV_BUFFER ) ;
}
int putDebugChar ( unsigned char byte )
{
if ( ! remoteDebugInitialized ) {
remoteDebugInitialized = 1 ;
debugInit ( YOSEMITE_BAUD_115200 ,
YOSEMITE_DATA_8BIT ,
YOSEMITE_PARITY_NONE , YOSEMITE_STOP_1BIT ) ;
}
while ( ( SERIAL_READ ( SERIAL_LINE_STATUS ) & 0x20 ) = = 0 ) ;
SERIAL_WRITE ( SERIAL_SEND_BUFFER , byte ) ;
return 1 ;
}