From: wdenk Date: Tue, 11 Sep 2001 10:22:41 +0000 (+0000) Subject: * Fixed register name (PSMR) X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=d1f48edaedc5e4bb0639a2fadba8feb484eac7b6;p=users%2Frw%2Fppcboot.git * Fixed register name (PSMR) Fixed FD mode for 8xx SCC ethernet Fixed RCCR init problem with I2C and SPI microcode relocation patch Fixed make problem under tcsh which causes conflicts with VENDOR variable * (PPC405GP only) Added interrupt driven serial port input mode with hardware handshake Patch by Morten Brørup, 27 Aug 2001 --- diff --git a/CHANGELOG b/CHANGELOG index 47d5578..d23d7bb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,16 @@ To do: Modifications for 1.0.5: ====================================================================== +* Fixed register name (PSMR) + Fixed FD mode for 8xx SCC ethernet + Fixed RCCR init problem with I2C and SPI microcode relocation patch + Fixed make problem under tcsh which causes conflicts with VENDOR + variable + +* (PPC405GP only) Added interrupt driven serial port input mode with + hardware handshake + Patch by Morten Brørup, 27 Aug 2001 + * Major modification for GTH board; added CONFIG_RESET_TO_RETRY configuration option Patch by Thomas Lange, 09 Aug 2001 diff --git a/Makefile b/Makefile index ae06d46..669cb6f 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,9 @@ endif export CROSS_COMPILE HOSTARCH +# Deal with colliding definitions from tcsh etc. +VENDOR= + ######################################################################### TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) diff --git a/README b/README index e75f35f..a076d72 100644 --- a/README +++ b/README @@ -279,6 +279,18 @@ The following options need to be configured: Select one of the baudrates listed in CFG_BAUDRATE_TABLE, see below. +- Interrupt driven serial port input: + CONFIG_SERIAL_SOFTWARE_FIFO + + PPC405GP only. + Use an interrupt handler for receiving data on the + serial port. It also enables using hardware handshake + (RTS/CTS) and UART's built-in FIFO. Set the number of + bytes the interrupt driven input buffer should have. + + Set to 0 to disable this feature (this is the default). + This will also disable hardware handshake. + - Boot Delay: CONFIG_BOOTDELAY - in seconds Delay before automatically booting the default image; set to -1 to disable autoboot. diff --git a/common/devices.c b/common/devices.c index 7f4a1ff..6d7fe33 100644 --- a/common/devices.c +++ b/common/devices.c @@ -53,10 +53,18 @@ static int drv_system_init (void) strcpy(serdev.name, "serial"); serdev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; +#if CONFIG_SERIAL_SOFTWARE_FIFO + serial_buffered_init(); + serdev.putc = serial_buffered_putc ; + serdev.puts = serial_buffered_puts ; + serdev.getc = serial_buffered_getc ; + serdev.tstc = serial_buffered_tstc ; +#else serdev.putc = serial_putc ; serdev.puts = serial_puts ; serdev.getc = serial_getc ; serdev.tstc = serial_tstc ; +#endif error = device_register (&serdev); diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c index 9f4ffb4..660e1f9 100644 --- a/cpu/mpc8260/ether_scc.c +++ b/cpu/mpc8260/ether_scc.c @@ -337,13 +337,13 @@ int eth_init(bd_t *bis) immr->im_scc[CONFIG_ETHER_INDEX-1].scc_psmr = SCC_PSMR_ENCRC | SCC_PSMR_NIB22 | #if defined(CONFIG_SCC_ENET_FULL_DUPLEX) - SCC_PMSR_FDE | + SCC_PSMR_FDE | #endif #if defined(CONFIG_SCC_ENET_NO_BROADCAST) - SCC_PMSR_BRO | + SCC_PSMR_BRO | #endif #if defined(CONFIG_SCC_ENET_PROMISCOUS) - SCC_PMSR_PRO | + SCC_PSMR_PRO | #endif 0; diff --git a/cpu/mpc8xx/cpu_init.c b/cpu/mpc8xx/cpu_init.c index 839cf27..f3e0b9a 100644 --- a/cpu/mpc8xx/cpu_init.c +++ b/cpu/mpc8xx/cpu_init.c @@ -223,6 +223,11 @@ cpu_init_f (volatile immap_t *immr) mbx_init(); #endif /* CONFIG_MBX */ +#ifdef CFG_RCCR /* must be done before cpm_load_patch() */ + /* write config value */ + immr->im_cpm.cp_rccr = CFG_RCCR; +#endif + #if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH) cpm_load_patch(immr); /* load mpc8xx microcode patch */ #endif @@ -234,7 +239,7 @@ cpu_init_f (volatile immap_t *immr) void cpu_init_r (bd_t *bd) { -#if defined(CFG_RTCSC) || defined(CFG_RCCR) || defined(CFG_RMDS) +#if defined(CFG_RTCSC) || defined(CFG_RMDS) volatile immap_t *immr = (volatile immap_t *)(bd->bi_immr_base); #endif @@ -245,11 +250,6 @@ cpu_init_r (bd_t *bd) immr->im_sit.sit_rtcsc = CFG_RTCSC; #endif -#ifdef CFG_RCCR - /* write config value */ - immr->im_cpm.cp_rccr = CFG_RCCR; -#endif - #ifdef CFG_RMDS /* write config value */ immr->im_cpm.cp_rmds = CFG_RMDS; diff --git a/cpu/mpc8xx/scc.c b/cpu/mpc8xx/scc.c index 11734bd..01c44b1 100644 --- a/cpu/mpc8xx/scc.c +++ b/cpu/mpc8xx/scc.c @@ -390,19 +390,21 @@ int eth_init(bd_t *bis) * CRC = 32-Bit CCITT * NIB = Begin searching for SFD 22 bits after RENA * FDE = Full Duplex Enable + * LPB = Loopback Enable (Needed when FDE is set) * BRO = Reject broadcast packets * PROMISCOUS = Catch all packets regardless of dest. MAC adress */ - immr->im_cpm.cp_scc[SCC_ENET].scc_psmr = SCC_PMSR_ENCRC | - SCC_PMSR_NIB22 | + immr->im_cpm.cp_scc[SCC_ENET].scc_psmr = SCC_PSMR_ENCRC | + SCC_PSMR_NIB22 | #if defined(CONFIG_SCC_ENET_FULL_DUPLEX) - SCC_PMSR_FDE | + SCC_PSMR_FDE | + SCC_PSMR_LPB | #endif #if defined(CONFIG_SCC_ENET_NO_BROADCAST) - SCC_PMSR_BRO | + SCC_PSMR_BRO | #endif #if defined(CONFIG_SCC_ENET_PROMISCOUS) - SCC_PMSR_PRO | + SCC_PSMR_PRO | #endif 0; diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c index aa43157..19971c4 100644 --- a/cpu/mpc8xx/serial.c +++ b/cpu/mpc8xx/serial.c @@ -460,7 +460,7 @@ serial_init (ulong cpu_clock, int baudrate) sp->scc_gsmrl |= (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - sp->scc_psmr |= SCU_PMSR_CL; + sp->scc_psmr |= SCU_PSMR_CL; /* Mask all interrupts and remove anything pending. */ diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index 5fd0322..9fd2384 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -45,6 +45,9 @@ #include #include +#if CONFIG_SERIAL_SOFTWARE_FIFO +#include +#endif /*****************************************************************************/ #ifdef CONFIG_IOP480 @@ -296,6 +299,20 @@ serial_tstc() //#define asyncRxBufferport1 UART0_BASE+0x00 +#if CONFIG_SERIAL_SOFTWARE_FIFO +/*-----------------------------------------------------------------------------+ +| Fifo ++-----------------------------------------------------------------------------*/ +typedef struct { + char * rx_buffer; + ulong rx_put; + ulong rx_get; +} serial_buffer_t; + +volatile static serial_buffer_t buf_info; +#endif + + /* * Minimal serial functions needed to use one of the SMC ports * as serial console interface. @@ -435,6 +452,113 @@ serial_tstc() return 0; } + +#if CONFIG_SERIAL_SOFTWARE_FIFO + +void serial_isr(void *arg) +{ + int space; + int c; + const int rx_get = buf_info.rx_get; + int rx_put = buf_info.rx_put; + + if (rx_get <= rx_put) { + space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get); + } else { + space = rx_get - rx_put; + } + while (serial_tstc()) { + c = serial_getc(); + if (space) { + buf_info.rx_buffer[rx_put++] = c; + space--; + } + if (rx_put==CONFIG_SERIAL_SOFTWARE_FIFO) rx_put = 0; + if ( space < CONFIG_SERIAL_SOFTWARE_FIFO/4 ) { + /* Stop flow by setting RTS inactive */ + out8(UART0_BASE + UART_MCR, in8(UART0_BASE + UART_MCR) & (0xFF^0x02)); + } + } + buf_info.rx_put = rx_put; +} + +void +serial_buffered_init (void) +{ + serial_puts( "Switching to interrupt driven serial input mode.\n" ); + buf_info.rx_buffer = malloc(CONFIG_SERIAL_SOFTWARE_FIFO); + buf_info.rx_put = 0; + buf_info.rx_get = 0; + + if (in8(UART0_BASE + UART_MSR) & 0x10) { + serial_puts( "Check CTS signal present on serial port: OK.\n" ); + } else { + serial_puts( "WARNING: CTS signal not present on serial port.\n" ); + } + + irq_install_handler(0/*UART0*/ /*int vec*/, serial_isr /*interrupt_handler_t *handler*/, (void*) &buf_info /*void *arg*/); + + /* Enable "RX Data Available" Interrupt on UART */ + /* out8(UART0_BASE + UART_IER, in8(UART0_BASE + UART_IER) |0x01); */ + out8(UART0_BASE + UART_IER, 0x01); + /* Set DTR active */ + out8(UART0_BASE + UART_MCR, in8(UART0_BASE + UART_MCR) | 0x01); + /* Start flow by setting RTS active */ + out8(UART0_BASE + UART_MCR, in8(UART0_BASE + UART_MCR) | 0x02); + /* Setup UART FIFO: RX trigger level: 4 byte, Enable FIFO */ + out8(UART0_BASE + UART_FCR, (1<<6)|1); +} + +void +serial_buffered_putc (const char c) +{ + /* Wait for CTS */ + while (!(in8(UART0_BASE + UART_MSR) & 0x10)) + ; + serial_putc(c); +} + +void +serial_buffered_puts (const char *s) +{ + serial_puts(s); +} + +int +serial_buffered_getc (void) +{ + int space; + int c; + int rx_get = buf_info.rx_get; + int rx_put; + while (rx_get == buf_info.rx_put) ; + c = buf_info.rx_buffer[rx_get++]; + if (rx_get==CONFIG_SERIAL_SOFTWARE_FIFO) rx_get = 0; + buf_info.rx_get = rx_get; + + rx_put = buf_info.rx_put; + if (rx_get <= rx_put) { + space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get); + } else { + space = rx_get - rx_put; + } + if ( space > CONFIG_SERIAL_SOFTWARE_FIFO/2) { + /* Start flow by setting RTS active */ + out8(UART0_BASE + UART_MCR, in8(UART0_BASE + UART_MCR) | 0x02); + } + + return c; +} + +int +serial_buffered_tstc (void) +{ + return (buf_info.rx_get != buf_info.rx_put)?1:0; +} + +#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */ + + #if (CONFIG_COMMANDS & CFG_CMD_KGDB) /* AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port diff --git a/include/commproc.h b/include/commproc.h index f27d07c..c813c2b 100644 --- a/include/commproc.h +++ b/include/commproc.h @@ -1121,21 +1121,21 @@ typedef struct scc_enet { #define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */ #define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */ -/* SCC Mode Register (PMSR) as used by Ethernet. +/* SCC Mode Register (PSMR) as used by Ethernet. */ -#define SCC_PMSR_HBC ((ushort)0x8000) /* Enable heartbeat */ -#define SCC_PMSR_FC ((ushort)0x4000) /* Force collision */ -#define SCC_PMSR_RSH ((ushort)0x2000) /* Receive short frames */ -#define SCC_PMSR_IAM ((ushort)0x1000) /* Check individual hash */ -#define SCC_PMSR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */ -#define SCC_PMSR_PRO ((ushort)0x0200) /* Promiscuous mode */ -#define SCC_PMSR_BRO ((ushort)0x0100) /* Catch broadcast pkts */ -#define SCC_PMSR_SBT ((ushort)0x0080) /* Special backoff timer */ -#define SCC_PMSR_LPB ((ushort)0x0040) /* Set Loopback mode */ -#define SCC_PMSR_SIP ((ushort)0x0020) /* Sample Input Pins */ -#define SCC_PMSR_LCW ((ushort)0x0010) /* Late collision window */ -#define SCC_PMSR_NIB22 ((ushort)0x000a) /* Start frame search */ -#define SCC_PMSR_FDE ((ushort)0x0001) /* Full duplex enable */ +#define SCC_PSMR_HBC ((ushort)0x8000) /* Enable heartbeat */ +#define SCC_PSMR_FC ((ushort)0x4000) /* Force collision */ +#define SCC_PSMR_RSH ((ushort)0x2000) /* Receive short frames */ +#define SCC_PSMR_IAM ((ushort)0x1000) /* Check individual hash */ +#define SCC_PSMR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */ +#define SCC_PSMR_PRO ((ushort)0x0200) /* Promiscuous mode */ +#define SCC_PSMR_BRO ((ushort)0x0100) /* Catch broadcast pkts */ +#define SCC_PSMR_SBT ((ushort)0x0080) /* Special backoff timer */ +#define SCC_PSMR_LPB ((ushort)0x0040) /* Set Loopback mode */ +#define SCC_PSMR_SIP ((ushort)0x0020) /* Sample Input Pins */ +#define SCC_PSMR_LCW ((ushort)0x0010) /* Late collision window */ +#define SCC_PSMR_NIB22 ((ushort)0x000a) /* Start frame search */ +#define SCC_PSMR_FDE ((ushort)0x0001) /* Full duplex enable */ /* Buffer descriptor control/status used by Ethernet receive. */ @@ -1215,21 +1215,21 @@ typedef struct scc_uart { #define UART_SCCM_TX ((ushort)0x0002) #define UART_SCCM_RX ((ushort)0x0001) -/* The SCC PMSR when used as a UART. +/* The SCC PSMR when used as a UART. */ -#define SCU_PMSR_FLC ((ushort)0x8000) -#define SCU_PMSR_SL ((ushort)0x4000) -#define SCU_PMSR_CL ((ushort)0x3000) -#define SCU_PMSR_UM ((ushort)0x0c00) -#define SCU_PMSR_FRZ ((ushort)0x0200) -#define SCU_PMSR_RZS ((ushort)0x0100) -#define SCU_PMSR_SYN ((ushort)0x0080) -#define SCU_PMSR_DRT ((ushort)0x0040) -#define SCU_PMSR_PEN ((ushort)0x0010) -#define SCU_PMSR_RPM ((ushort)0x000c) -#define SCU_PMSR_REVP ((ushort)0x0008) -#define SCU_PMSR_TPM ((ushort)0x0003) -#define SCU_PMSR_TEVP ((ushort)0x0003) +#define SCU_PSMR_FLC ((ushort)0x8000) +#define SCU_PSMR_SL ((ushort)0x4000) +#define SCU_PSMR_CL ((ushort)0x3000) +#define SCU_PSMR_UM ((ushort)0x0c00) +#define SCU_PSMR_FRZ ((ushort)0x0200) +#define SCU_PSMR_RZS ((ushort)0x0100) +#define SCU_PSMR_SYN ((ushort)0x0080) +#define SCU_PSMR_DRT ((ushort)0x0040) +#define SCU_PSMR_PEN ((ushort)0x0010) +#define SCU_PSMR_RPM ((ushort)0x000c) +#define SCU_PSMR_REVP ((ushort)0x0008) +#define SCU_PSMR_TPM ((ushort)0x0003) +#define SCU_PSMR_TEVP ((ushort)0x0003) /* CPM Transparent mode SCC. */ diff --git a/include/config_WALNUT405.h b/include/config_WALNUT405.h index b38d880..0456f1c 100644 --- a/include/config_WALNUT405.h +++ b/include/config_WALNUT405.h @@ -59,6 +59,12 @@ #define CONFIG_BOOTCOMMAND "bootp" /* autoboot command */ #endif +/* Size (bytes) of interrupt driven serial port buffer. + * Set to 0 to use polling instead of interrupts. + * Setting to 0 will also disable RTS/CTS handshaking. + */ +#define CONFIG_SERIAL_SOFTWARE_FIFO 4000 + #if 0 #define CONFIG_BOOTARGS "root=/dev/nfs " \ "ip=192.168.2.176:192.168.2.190:192.168.2.79:255.255.255.0 " \ diff --git a/include/ppcboot.h b/include/ppcboot.h index bd1fa41..b7bee0b 100644 --- a/include/ppcboot.h +++ b/include/ppcboot.h @@ -313,6 +313,13 @@ void serial_puts (const char *); void serial_addr (unsigned int); int serial_getc (void); int serial_tstc (void); +#if CONFIG_SERIAL_SOFTWARE_FIFO +void serial_buffered_init (void); +void serial_buffered_putc (const char); +void serial_buffered_puts (const char *); +int serial_buffered_getc (void); +int serial_buffered_tstc (void); +#endif /* $(CPU)/start.S */ #ifdef CONFIG_8xx