From: Stuart M. <Stu...@st...> - 2000-05-24 12:33:17
|
Folks I've uploaded a small patch to patch manager on SourceForge (and a copy is also included in this email) for a few changes I've made here to the serial port support: - configure the baud rate, bits, and parity for the serial console at boot time - record the clock values discovered at boot time in the cpuinfo info structure, and print the values as part of /proc/cpuinfo - use the peripherial module clock when calculating values for the SCI(F) baud rate (BBR) - pass through the baud rate from the serial console to the full serial driver - minimal support for the STMicroelectronics Overdrive board I've set the default baud rate to 9600, which appears to be the default for all other serial drivers. However the 'console' command line parameter now works, so add something like: console=ttyS0,115200 to get the old behaviour back. The patch is against the latest version on Sourceforge (as of 09:00 24th May). Unfortunatly some of this clashes with the patch generated by Pierre-Philippe. I think we had similar objectives for the SCI changes, although his patch also contains quite a few other things which are specific to his hardware. IMHO this way of doing things is a bit more general. By the way, Pierre's patch on sourceforge appears to be corrupt. Stuart --------------------------------------------------------------------------- Index: kernel/arch/sh/config.in =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/config.in,v retrieving revision 1.5 diff -u -r1.5 config.in --- kernel/arch/sh/config.in 2000/05/04 06:32:44 1.5 +++ kernel/arch/sh/config.in 2000/05/24 10:44:03 @@ -17,28 +17,47 @@ comment 'Processor type and features' choice 'SuperH system type' \ "Generic CONFIG_SH_GENERIC \ - SolutionEngine CONFIG_SH_SOLUTION_ENGINE" Generic + SolutionEngine CONFIG_SH_SOLUTION_ENGINE \ + Overdrive CONFIG_SH_OVERDRIVE" Generic -choice 'Processor type' \ - "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ - SH7709 CONFIG_CPU_SUBTYPE_SH7709 \ - SH7750 CONFIG_CPU_SUBTYPE_SH7750" SH7708 -if [ "$CONFIG_CPU_SUBTYPE_SH7708" = "y" ]; then - define_bool CONFIG_CPU_SH3 y - define_bool CONFIG_CPU_SH4 n -fi -if [ "$CONFIG_CPU_SUBTYPE_SH7709" = "y" ]; then - define_bool CONFIG_CPU_SH3 y - define_bool CONFIG_CPU_SH4 n -fi -if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then - define_bool CONFIG_CPU_SH3 n - define_bool CONFIG_CPU_SH4 y + +if [ "$CONFIG_SH_OVERDRIVE" = "n" ]; then + choice 'Processor type' \ + "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ + SH7709 CONFIG_CPU_SUBTYPE_SH7709 \ + SH7750 CONFIG_CPU_SUBTYPE_SH7750" SH7708 + if [ "$CONFIG_CPU_SUBTYPE_SH7708" = "y" ]; then + define_bool CONFIG_CPU_SH3 y + define_bool CONFIG_CPU_SH4 n + fi + if [ "$CONFIG_CPU_SUBTYPE_SH7709" = "y" ]; then + define_bool CONFIG_CPU_SH3 y + define_bool CONFIG_CPU_SH4 n + fi + if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then + define_bool CONFIG_CPU_SH3 n + define_bool CONFIG_CPU_SH4 y + fi +else + define_bool CONFIG_CPU_SUBTYPE_SH7708 n + define_bool CONFIG_CPU_SUBTYPE_SH7709 n + define_bool CONFIG_CPU_SUBTYPE_SH7750 y + define_bool CONFIG_CPU_SH3 n + define_bool CONFIG_CPU_SH4 y fi + bool 'Little Endian' CONFIG_LITTLE_ENDIAN + if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then define_hex CONFIG_MEMORY_START 0c000000 -else +fi + +if [ "$CONFIG_SH_OVERDRIVE" = "y" ]; then + define_hex CONFIG_MEMORY_START 0c000000 + define_hex CONFIG_IOPORT_START ba000000 +fi + +if [ "$CONFIG_SH_GENERIC" = "y" ]; then hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 hex 'I/O port offset address' CONFIG_IOPORT_START ba000000 fi Index: kernel/arch/sh/kernel/Makefile =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/Makefile,v retrieving revision 1.3 diff -u -r1.3 Makefile --- kernel/arch/sh/kernel/Makefile 2000/05/03 02:24:42 1.3 +++ kernel/arch/sh/kernel/Makefile 2000/05/24 10:44:03 @@ -28,6 +28,10 @@ O_OBJS += setup_se.o io_se.o endif +ifdef CONFIG_SH_OVERDRIVE +O_OBJS += setup_od.o io_generic.o +endif + ifdef CONFIG_CPU_SH4 O_OBJS += fpu.o endif Index: kernel/arch/sh/kernel/setup.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/setup.c,v retrieving revision 1.3 diff -u -r1.3 setup.c --- kernel/arch/sh/kernel/setup.c 2000/04/28 17:58:50 1.3 +++ kernel/arch/sh/kernel/setup.c 2000/05/24 10:44:03 @@ -327,5 +327,13 @@ (loops_per_sec+2500)/500000, ((loops_per_sec+2500)/5000) % 100); +#define PRINT_CLOCK(name, value) \ + p += sprintf(p, name " clock: %d.%02dMHz\n", \ + ((value) / 1000000), ((value) % 1000000)/10000) + + PRINT_CLOCK("CPU", boot_cpu_data.cpu_clock); + PRINT_CLOCK("Bus", boot_cpu_data.bus_clock); + PRINT_CLOCK("Peripherial module", boot_cpu_data.module_clock); + return p - buffer; } Index: kernel/arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/time.c,v retrieving revision 1.9 diff -u -r1.9 time.c --- kernel/arch/sh/kernel/time.c 2000/05/14 08:41:25 1.9 +++ kernel/arch/sh/kernel/time.c 2000/05/24 10:44:04 @@ -444,6 +444,11 @@ printk("Interval = %ld\n", interval); + current_cpu_data.cpu_clock = cpu_clock; + current_cpu_data.master_clock = master_clock; + current_cpu_data.bus_clock = bus_clock; + current_cpu_data.module_clock = module_clock; + /* Start TMU0 */ ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); Index: kernel/drivers/char/sh-sci.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/char/sh-sci.c,v retrieving revision 1.8 diff -u -r1.8 sh-sci.c --- kernel/drivers/char/sh-sci.c 2000/05/22 09:41:31 1.8 +++ kernel/drivers/char/sh-sci.c 2000/05/24 10:44:05 @@ -31,7 +31,9 @@ #include <linux/malloc.h> #include <linux/init.h> #include <linux/delay.h> +#ifdef CONFIG_SERIAL_CONSOLE #include <linux/console.h> +#endif #include <asm/system.h> #include <asm/io.h> @@ -50,6 +52,10 @@ struct sci_port sci_ports[1]; +#ifdef CONFIG_SERIAL_CONSOLE +static struct console sercons; +#endif + /* Function prototypes */ static void sci_disable_tx_interrupts(void *ptr); static void sci_enable_tx_interrupts(void *ptr); @@ -114,11 +120,11 @@ */ } -static void sci_set_baud(struct sci_port *port) +static void sci_set_baud(int baud) { int t; - switch (port->gs.baud) { + switch (baud) { case 0: t = -1; break; @@ -138,14 +144,14 @@ t = BPS_38400; break; default: - printk(KERN_INFO "sci: unsupported baud rate: %d, use 115200 instead.\n", port->gs.baud); + printk(KERN_INFO "sci: unsupported baud rate: %d, use 115200 instead.\n", baud); case 115200: t = BPS_115200; break; } if (t > 0) { - sci_setsignals (port, 1, -1); + /* sci_setsignals (port, 1, -1); */ if(t >= 256) { ctrl_out((ctrl_in(SCSMR) & ~3) | 1, SCSMR); t >>= 2; @@ -155,11 +161,11 @@ while (ctrl_inw(RFCR) < WAIT_RFCR_COUNTER) ; } else { - sci_setsignals (port, 0, -1); + /* sci_setsignals (port, 0, -1); */ } } -static void sci_set_termios_cflag(struct sci_port *port) +static void sci_set_termios_cflag(int cflag, int baud) { unsigned short status; unsigned short smr_val; @@ -171,8 +177,6 @@ status = ctrl_in(SC_SR); while (!(status & SCI_TEND)); - port->old_cflag = port->gs.tty->termios->c_cflag; - ctrl_out(0x00, SCSCR); /* TE=0, RE=0, CKE1=0 */ #if defined(CONFIG_SH_SCIF_SERIAL) ctrl_out(fcr_val, SCFCR); @@ -180,13 +184,13 @@ #endif smr_val = ctrl_in(SCSMR) & 3; - if ((port->gs.tty->termios->c_cflag & CSIZE) == CS7) + if ((cflag & CSIZE) == CS7) smr_val |= 0x40; - if (C_PARENB(port->gs.tty)) + if (cflag & PARENB) smr_val |= 0x20; - if (C_PARODD(port->gs.tty)) + if (cflag & PARODD) smr_val |= 0x10; - if (C_CSTOPB(port->gs.tty)) + if (cflag & CSTOPB) smr_val |= 0x08; ctrl_out(smr_val, SCSMR); @@ -201,7 +205,7 @@ ctrl_outw(data&0x0fcf, SCPCR); } #endif - if (C_CRTSCTS(port->gs.tty)) + if (cflag & CRTSCTS) fcr_val |= 0x08; else { #if defined(__sh3__) @@ -223,17 +227,19 @@ ctrl_out(fcr_val, SCFCR); #endif - sci_set_baud(port); + sci_set_baud(baud); ctrl_out(SCSCR_INIT, SCSCR); /* TIE=0,RIE=0,TE=1,RE=1 */ - sci_enable_rx_interrupts(port); } static int sci_set_real_termios(void *ptr) { struct sci_port *port = ptr; - if (port->old_cflag != port->gs.tty->termios->c_cflag) - sci_set_termios_cflag(port); + if (port->old_cflag != port->gs.tty->termios->c_cflag) { + port->old_cflag = port->gs.tty->termios->c_cflag; + sci_set_termios_cflag(port->old_cflag, port->gs.baud); + sci_enable_rx_interrupts(port); + } /* Tell line discipline whether we will do input cooking */ if (I_OTHER(port->gs.tty)) @@ -521,6 +527,13 @@ port->gs.tty = tty; port->gs.count++; +#ifdef CONFIG_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + } +#endif + /* * Start up serial port */ @@ -687,7 +700,7 @@ sci_driver.subtype = SERIAL_TYPE_NORMAL; sci_driver.init_termios = tty_std_termios; sci_driver.init_termios.c_cflag = - B115200 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS; + B9600 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS; sci_driver.flags = TTY_DRIVER_REAL_RAW; sci_driver.refcount = &sci_refcount; sci_driver.table = sci_table; @@ -851,7 +864,7 @@ */ static int __init serial_console_setup(struct console *co, char *options) { - int baud = 115200; + int baud = 9600; int bits = 8; int parity = 'n'; int cflag = CREAD | HUPCL | CLOCAL; @@ -885,6 +898,7 @@ case 9600: default: cflag |= B9600; + baud = 9600; break; } switch (bits) { @@ -905,8 +919,9 @@ break; } co->cflag = cflag; + + sci_set_termios_cflag(cflag, baud); - /* XXX: set baud, char, and parity here. */ return 0; } Index: kernel/drivers/char/sh-sci.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/char/sh-sci.h,v retrieving revision 1.6 diff -u -r1.6 sh-sci.h --- kernel/drivers/char/sh-sci.h 2000/05/22 09:41:31 1.6 +++ kernel/drivers/char/sh-sci.h 2000/05/24 10:44:05 @@ -193,22 +193,17 @@ * the SCSMR register would also need to be set to non-zero values. * * -- Greg Banks 27Feb2000 + * + * Answer: The SCBRR register is only eight bits, and the value in + * it gets larger with lower baud rates. At around 2400 (depending on + * the peripherial module clock) you run out of bits. However the + * lower two bits of SCSMR allow the module clock to be divided down, + * scaling the value which is needed in SCBRR. + * + * -- Stuart Menefy - 23 May 2000 */ -/* - * XXX: Well, this is not relevant... - * Should we have config option for peripheral clock? - * Or we get the value from time.c. - */ -#if defined(__sh3__) -#if defined(CONFIG_CPU_SUBTYPE_SH7709) -#define PCLK 33333333 -#else -#define PCLK 14745600 /* Isn't it 15MHz? */ -#endif -#elif defined(__SH4__) -#define PCLK 33333333 -#endif +#define PCLK (current_cpu_data.module_clock) #define SCBRR_VALUE(bps) (PCLK/(32*bps)-1) #define BPS_2400 SCBRR_VALUE(2400) Index: kernel/include/asm-sh/processor.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/processor.h,v retrieving revision 1.2 diff -u -r1.2 processor.h --- kernel/include/asm-sh/processor.h 2000/04/14 17:25:44 1.2 +++ kernel/include/asm-sh/processor.h 2000/05/24 10:44:09 @@ -36,6 +36,7 @@ unsigned long *pgd_quick; unsigned long *pte_quick; unsigned long pgtable_cache_sz; + unsigned int cpu_clock, master_clock, bus_clock, module_clock; }; extern struct sh_cpuinfo boot_cpu_data; Index: kernel/arch/sh/kernel/setup_od.c =================================================================== diff -u -r0.0 setup_od.c --- /dev/null Tue May 5 21:32:27 1998 +++ kernel/arch/sh/kernel/setup_od.c Tue May 23 22:15:48 2000 @@ -0,0 +1,35 @@ +/* $Id$ + * + * linux/arch/sh/kernel/setup_od.c + * + * Copyright (C) 2000 Stuart Menefy + * + * STMicroelectronics Overdrive Support. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> + +/* + * Initialize the board + */ +int __init setup_od(void) +{ + /* Enable RS232 receive buffers */ + volatile int* p = (volatile int*)0xa3000000; + +#if defined(CONFIG_SH_ORION) + *p=1; +#elif defined(CONFIG_SH_OVERDRIVE) + *p=0x1e; +#else +#error Illegal configuration +#endif + + printk(KERN_INFO "STMicroelectronics Overdrive Setup...done\n"); + return 0; +} + +module_init(setup_od); |