Commit 429e654d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] sh: sh-sci updates.

From: Paul Mundt <lethal@Linux-SH.ORG>

This adds support for the SH7300 as well as the SH5-101/103 processors as well
as specific board support for the RTS7751R2D.

In addition to this, the sh early printk code is gutted so that we use the
generic CONFIG_EARLY_PRINTK interfaces instead.
Signed-off-by: default avatarHiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 16450b81
...@@ -90,12 +90,12 @@ static struct uart_driver sci_uart_driver; ...@@ -90,12 +90,12 @@ static struct uart_driver sci_uart_driver;
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
static void handle_error(struct sci_port *port) static void handle_error(struct uart_port *port)
{ /* Clear error flags */ { /* Clear error flags */
sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
} }
static int get_char(struct sci_port *port) static int get_char(struct uart_port *port)
{ {
unsigned long flags; unsigned long flags;
unsigned short status; unsigned short status;
...@@ -332,11 +332,11 @@ static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) ...@@ -332,11 +332,11 @@ static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag)
#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
#if defined(CONFIG_CPU_SH3) #if defined(CONFIG_CPU_SH3)
/* For SH7707, SH7709, SH7709A, SH7729 */ /* For SH7707, SH7709, SH7709A, SH7729, SH7300*/
static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
{ {
unsigned int fcr_val = 0; unsigned int fcr_val = 0;
#if !defined(CONFIG_CPU_SUBTYPE_SH7300) /* SH7300 doesn't use RTS/CTS */
{ {
unsigned short data; unsigned short data;
...@@ -360,6 +360,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) ...@@ -360,6 +360,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
/* Set /RTS2 (bit6) = 0 */ /* Set /RTS2 (bit6) = 0 */
ctrl_outb(data&0xbf, SCPDR); ctrl_outb(data&0xbf, SCPDR);
} }
#endif
sci_out(port, SCFCR, fcr_val); sci_out(port, SCFCR, fcr_val);
} }
...@@ -420,7 +421,7 @@ static void sci_transmit_chars(struct uart_port *port) ...@@ -420,7 +421,7 @@ static void sci_transmit_chars(struct uart_port *port)
#if !defined(SCI_ONLY) #if !defined(SCI_ONLY)
if (port->type == PORT_SCIF) { if (port->type == PORT_SCIF) {
txroom = 16 - (sci_in(port, SCFDR)>>8); txroom = SCIF_TXROOM_MAX - (sci_in(port, SCFDR)>>8);
} else { } else {
txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0; txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
} }
...@@ -488,7 +489,7 @@ static inline void sci_receive_chars(struct uart_port *port, ...@@ -488,7 +489,7 @@ static inline void sci_receive_chars(struct uart_port *port,
while (1) { while (1) {
#if !defined(SCI_ONLY) #if !defined(SCI_ONLY)
if (port->type == PORT_SCIF) { if (port->type == PORT_SCIF) {
count = sci_in(port, SCFDR)&0x001f; count = sci_in(port, SCFDR)&SCIF_RFDC_MASK ;
} else { } else {
count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0; count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
} }
...@@ -671,8 +672,7 @@ static inline int sci_handle_breaks(struct uart_port *port) ...@@ -671,8 +672,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
pr_debug("sci: BREAK detected\n"); pr_debug("sci: BREAK detected\n");
} }
#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1) || \ #if defined(SCIF_ORER)
defined(CONFIG_CPU_SUBTYPE_SH7760)
/* XXX: Handle SCIF overrun error */ /* XXX: Handle SCIF overrun error */
if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
sci_out(port, SCLSR, 0); sci_out(port, SCLSR, 0);
...@@ -726,6 +726,19 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs) ...@@ -726,6 +726,19 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
} }
} else { } else {
#if defined(SCIF_ORER)
if((sci_in(port, SCLSR) & SCIF_ORER) != 0) {
struct tty_struct *tty = port->info->tty;
sci_out(port, SCLSR, 0);
if(tty->flip.count<TTY_FLIPBUF_SIZE) {
*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
tty->flip.count++;
tty_flip_buffer_push(tty);
pr_debug("scif: overrun error\n");
}
}
#endif
sci_rx_interrupt(irq, ptr, regs); sci_rx_interrupt(irq, ptr, regs);
} }
...@@ -748,6 +761,30 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs) ...@@ -748,6 +761,30 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
{
unsigned short ssr_status, scr_status;
struct uart_port *port = ptr;
ssr_status = sci_in(port,SCxSR);
scr_status = sci_in(port,SCSCR);
/* Tx Interrupt */
if ((ssr_status&0x0020) && (scr_status&0x0080))
sci_tx_interrupt(irq, ptr, regs);
/* Rx Interrupt */
if ((ssr_status&0x0002) && (scr_status&0x0040))
sci_rx_interrupt(irq, ptr, regs);
/* Error Interrupt */
if ((ssr_status&0x0080) && (scr_status&0x0400))
sci_er_interrupt(irq, ptr, regs);
/* Break Interrupt */
if ((ssr_status&0x0010) && (scr_status&0x0200))
sci_br_interrupt(irq, ptr, regs);
return IRQ_HANDLED;
}
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
/* /*
* Here we define a transistion notifier so that we can update all of our * Here we define a transistion notifier so that we can update all of our
...@@ -797,14 +834,26 @@ static int sci_request_irq(struct sci_port *port) ...@@ -797,14 +834,26 @@ static int sci_request_irq(struct sci_port *port)
const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full",
"SCI Transmit Data Empty", "SCI Break" }; "SCI Transmit Data Empty", "SCI Break" };
for (i = 0; i < ARRAY_SIZE(handlers); i++) { if (port->irqs[0] == port->irqs[1]) {
if (!port->irqs[i]) if (!port->irqs[0]) {
continue; printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n");
if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT, return -ENODEV;
desc[i], port)) { }
if (request_irq(port->irqs[0], sci_mpxed_interrupt, SA_INTERRUPT,
"sci", port)) {
printk(KERN_ERR "sci: Cannot allocate irq.\n"); printk(KERN_ERR "sci: Cannot allocate irq.\n");
return -ENODEV; return -ENODEV;
} }
} else {
for (i = 0; i < ARRAY_SIZE(handlers); i++) {
if (!port->irqs[i])
continue;
if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
desc[i], port)) {
printk(KERN_ERR "sci: Cannot allocate irq.\n");
return -ENODEV;
}
}
} }
return 0; return 0;
...@@ -814,11 +863,18 @@ static void sci_free_irq(struct sci_port *port) ...@@ -814,11 +863,18 @@ static void sci_free_irq(struct sci_port *port)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { if (port->irqs[0] == port->irqs[1]) {
if (!port->irqs[i]) if (!port->irqs[0])
continue; printk("sci: sci_free_irq error\n");
else
free_irq(port->irqs[i], port); free_irq(port->irqs[0], port);
} else {
for (i = 0; i < ARRAY_SIZE(port->irqs); i++) {
if (!port->irqs[i])
continue;
free_irq(port->irqs[i], port);
}
} }
} }
...@@ -873,7 +929,7 @@ static void sci_start_rx(struct uart_port *port, unsigned int tty_start) ...@@ -873,7 +929,7 @@ static void sci_start_rx(struct uart_port *port, unsigned int tty_start)
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */ /* Set RIE (Receive Interrupt Enable) bit in SCSCR */
local_irq_save(flags); local_irq_save(flags);
ctrl = sci_in(port, SCSCR); ctrl = sci_in(port, SCSCR);
ctrl |= SCI_CTRL_FLAGS_RIE; ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
sci_out(port, SCSCR, ctrl); sci_out(port, SCSCR, ctrl);
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -886,7 +942,7 @@ static void sci_stop_rx(struct uart_port *port) ...@@ -886,7 +942,7 @@ static void sci_stop_rx(struct uart_port *port)
/* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
local_irq_save(flags); local_irq_save(flags);
ctrl = sci_in(port, SCSCR); ctrl = sci_in(port, SCSCR);
ctrl &= ~SCI_CTRL_FLAGS_RIE; ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
sci_out(port, SCSCR, ctrl); sci_out(port, SCSCR, ctrl);
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -976,7 +1032,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios, ...@@ -976,7 +1032,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios,
case 38400: t = BPS_38400; break; case 38400: t = BPS_38400; break;
case 57600: t = BPS_57600; break; case 57600: t = BPS_57600; break;
case 115200: t = BPS_115200; break; case 115200: t = BPS_115200; break;
default: t = BPS_115200; break; default: t = SCBRR_VALUE(baud); break;
} }
if (t > 0) { if (t > 0) {
...@@ -1026,6 +1082,13 @@ static void sci_config_port(struct uart_port *port, int flags) ...@@ -1026,6 +1082,13 @@ static void sci_config_port(struct uart_port *port, int flags)
struct sci_port *s = &sci_ports[port->line]; struct sci_port *s = &sci_ports[port->line];
port->type = s->type; port->type = s->type;
#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
if (port->mapbase == 0)
port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
port->membase = (void *)port->mapbase;
#endif
} }
static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
...@@ -1119,6 +1182,36 @@ static struct sci_port sci_ports[SCI_NPORTS] = { ...@@ -1119,6 +1182,36 @@ static struct sci_port sci_ports[SCI_NPORTS] = {
.irqs = SH3_IRDA_IRQS, .irqs = SH3_IRDA_IRQS,
.init_pins = sci_init_pins_irda, .init_pins = sci_init_pins_irda,
} }
#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
{
.port = {
.membase = (void *)0xA4430000,
.mapbase = 0xA4430000,
.iotype = SERIAL_IO_MEM,
.irq = 25,
.ops = &sci_uart_ops,
.flags = ASYNC_BOOT_AUTOCONF,
.line = 0,
},
.type = PORT_SCIF,
.irqs = SH7300_SCIF0_IRQS,
.init_pins = sci_init_pins_scif,
},
#elif defined(CONFIG_SH_RTS7751R2D)
{
.port = {
.membase = (void *)0xffe80000,
.mapbase = 0xffe80000,
.iotype = SERIAL_IO_MEM,
.irq = 43,
.ops = &sci_uart_ops,
.flags = ASYNC_BOOT_AUTOCONF,
.line = 0,
},
.type = PORT_SCIF,
.irqs = SH4_SCIF_IRQS,
.init_pins = sci_init_pins_scif,
},
#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
{ {
.port = { .port = {
...@@ -1220,6 +1313,19 @@ static struct sci_port sci_ports[SCI_NPORTS] = { ...@@ -1220,6 +1313,19 @@ static struct sci_port sci_ports[SCI_NPORTS] = {
.irqs = SH4_SCIF_IRQS, .irqs = SH4_SCIF_IRQS,
.init_pins = sci_init_pins_scif, .init_pins = sci_init_pins_scif,
}, },
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
{
.port = {
.iotype = SERIAL_IO_MEM,
.irq = 42,
.ops = &sci_uart_ops,
.flags = ASYNC_BOOT_AUTOCONF,
.line = 0,
},
.type = PORT_SCIF,
.irqs = SH5_SCIF_IRQS,
.init_pins = sci_init_pins_scif,
},
#elif defined(CONFIG_H83007) || defined(CONFIG_H83068) #elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
{ {
.port = { .port = {
...@@ -1338,6 +1444,11 @@ static int __init serial_console_setup(struct console *co, char *options) ...@@ -1338,6 +1444,11 @@ static int __init serial_console_setup(struct console *co, char *options)
port = &serial_console_port->port; port = &serial_console_port->port;
port->type = serial_console_port->type; port->type = serial_console_port->type;
#ifdef CONFIG_SUPERH64
/* This is especially needed on sh64 to remap the SCIF */
sci_config_port(port, 0);
#endif
/* /*
* We need to set the initial uartclk here, since otherwise it will * We need to set the initial uartclk here, since otherwise it will
* only ever be setup at sci_init() time. * only ever be setup at sci_init() time.
...@@ -1374,18 +1485,7 @@ static struct console serial_console = { ...@@ -1374,18 +1485,7 @@ static struct console serial_console = {
static int __init sci_console_init(void) static int __init sci_console_init(void)
{ {
#ifdef CONFIG_SH_EARLY_PRINTK
extern void sh_console_unregister(void);
/*
* Now that the real console is available, unregister the one we
* used while first booting.
*/
sh_console_unregister();
#endif
register_console(&serial_console); register_console(&serial_console);
return 0; return 0;
} }
...@@ -1452,7 +1552,6 @@ static struct console kgdb_console = { ...@@ -1452,7 +1552,6 @@ static struct console kgdb_console = {
static int __init kgdb_console_init(void) static int __init kgdb_console_init(void)
{ {
register_console(&kgdb_console); register_console(&kgdb_console);
return 0; return 0;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (C) 2000 Greg Banks * Copyright (C) 2000 Greg Banks
* Copyright (C) 2002, 2003 Paul Mundt * Copyright (C) 2002, 2003 Paul Mundt
* Modified to support multiple serial ports. Stuart Menefy (May 2000). * Modified to support multiple serial ports. Stuart Menefy (May 2000).
* Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003).
* Modified to support H8/300 Series Yoshinori Sato (Feb 2004). * Modified to support H8/300 Series Yoshinori Sato (Feb 2004).
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -36,12 +37,14 @@ ...@@ -36,12 +37,14 @@
#define SH7760_SCIF0_IRQS { 52, 53, 55, 54 } #define SH7760_SCIF0_IRQS { 52, 53, 55, 54 }
#define SH7760_SCIF1_IRQS { 72, 73, 75, 74 } #define SH7760_SCIF1_IRQS { 72, 73, 75, 74 }
#define SH7760_SCIF2_IRQS { 76, 77, 79, 78 } #define SH7760_SCIF2_IRQS { 76, 77, 79, 78 }
#define SH7300_SCIF0_IRQS {80, 80, 80, 80 }
#define H8300H_SCI_IRQS0 {52, 53, 54, 0 } #define H8300H_SCI_IRQS0 {52, 53, 54, 0 }
#define H8300H_SCI_IRQS1 {56, 57, 58, 0 } #define H8300H_SCI_IRQS1 {56, 57, 58, 0 }
#define H8300H_SCI_IRQS2 {60, 61, 62, 0 } #define H8300H_SCI_IRQS2 {60, 61, 62, 0 }
#define H8S_SCI_IRQS0 {88, 89, 90, 0 } #define H8S_SCI_IRQS0 {88, 89, 90, 0 }
#define H8S_SCI_IRQS1 {92, 93, 94, 0 } #define H8S_SCI_IRQS1 {92, 93, 94, 0 }
#define H8S_SCI_IRQS2 {96, 97, 98, 0 } #define H8S_SCI_IRQS2 {96, 97, 98, 0 }
#define SH5_SCIF_IRQS {39, 40, 42, 0 }
#if defined(CONFIG_CPU_SUBTYPE_SH7708) #if defined(CONFIG_CPU_SUBTYPE_SH7708)
# define SCI_NPORTS 1 # define SCI_NPORTS 1
...@@ -54,6 +57,13 @@ ...@@ -54,6 +57,13 @@
# define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */
# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
# define SCI_AND_SCIF # define SCI_AND_SCIF
#elif defined(CONFIG_SH_RTS7751R2D)
# define SCI_NPORTS 1
# define SCSPTR1 0xffe0001c /* 8 bit SCI */
# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
# define SCI_NPORTS 2 # define SCI_NPORTS 2
# define SCSPTR1 0xffe0001c /* 8 bit SCI */ # define SCSPTR1 0xffe0001c /* 8 bit SCI */
...@@ -68,9 +78,15 @@ ...@@ -68,9 +78,15 @@
# define SCSPTR0 0xfe600000 /* 16 bit SCIF */ # define SCSPTR0 0xfe600000 /* 16 bit SCIF */
# define SCSPTR1 0xfe610000 /* 16 bit SCIF */ # define SCSPTR1 0xfe610000 /* 16 bit SCIF */
# define SCSPTR2 0xfe620000 /* 16 bit SCIF */ # define SCSPTR2 0xfe620000 /* 16 bit SCIF */
# define SCIF_ORDER 0x0001 /* overrun error bit */ # define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY # define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
# define SCI_NPORTS 1
# define SCPCR 0xA4050116 /* 16 bit SCIF */
# define SCPDR 0xA4050136 /* 16 bit SCIF */
# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
# define SCI_NPORTS 2 # define SCI_NPORTS 2
# define SCSPTR1 0xffe00020 /* 16 bit SCIF */ # define SCSPTR1 0xffe00020 /* 16 bit SCIF */
...@@ -78,6 +94,22 @@ ...@@ -78,6 +94,22 @@
# define SCIF_ORER 0x0001 /* overrun error bit */ # define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY # define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
# include <asm/hardware.h>
# define SCIF_BASE_ADDR 0x01030000
# define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR
# define SCIF_PTR2_OFFS 0x0000020
# define SCIF_LSR2_OFFS 0x0000024
# define SCI_NPORTS 1
# define SCI_INIT { \
{ {}, PORT_SCIF, 0, \
SH5_SCIF_IRQS, sci_init_pins_scif } \
}
# define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */
# define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,
TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_H83007) || defined(CONFIG_H83068) #elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
# define SCI_NPORTS 3 # define SCI_NPORTS 3
# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
...@@ -97,7 +129,11 @@ ...@@ -97,7 +129,11 @@
#define SCI_CTRL_FLAGS_RIE 0x40 /* all */ #define SCI_CTRL_FLAGS_RIE 0x40 /* all */
#define SCI_CTRL_FLAGS_TE 0x20 /* all */ #define SCI_CTRL_FLAGS_TE 0x20 /* all */
#define SCI_CTRL_FLAGS_RE 0x10 /* all */ #define SCI_CTRL_FLAGS_RE 0x10 /* all */
/* SCI_CTRL_FLAGS_REIE 0x08 * 7750 SCIF */ #if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
#else
#define SCI_CTRL_FLAGS_REIE 0
#endif
/* SCI_CTRL_FLAGS_MPIE 0x08 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ /* SCI_CTRL_FLAGS_MPIE 0x08 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
/* SCI_CTRL_FLAGS_TEIE 0x04 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ /* SCI_CTRL_FLAGS_TEIE 0x04 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
/* SCI_CTRL_FLAGS_CKE1 0x02 * all */ /* SCI_CTRL_FLAGS_CKE1 0x02 * all */
...@@ -125,7 +161,16 @@ ...@@ -125,7 +161,16 @@
#define SCIF_RDF 0x0002 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */ #define SCIF_RDF 0x0002 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_DR 0x0001 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */ #define SCIF_DR 0x0001 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
#define SCIF_ORER 0x0200
#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
#define SCIF_RFDC_MASK 0x007f
#define SCIF_TXROOM_MAX 64
#else
#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) #define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
#define SCIF_RFDC_MASK 0x001f
#define SCIF_TXROOM_MAX 16
#endif
#if defined(SCI_ONLY) #if defined(SCI_ONLY)
# define SCxSR_TEND(port) SCI_TEND # define SCxSR_TEND(port) SCI_TEND
...@@ -145,14 +190,25 @@ ...@@ -145,14 +190,25 @@
# define SCxSR_ERRORS(port) SCIF_ERRORS # define SCxSR_ERRORS(port) SCIF_ERRORS
# define SCxSR_RDxF(port) SCIF_RDF # define SCxSR_RDxF(port) SCIF_RDF
# define SCxSR_TDxE(port) SCIF_TDFE # define SCxSR_TDxE(port) SCIF_TDFE
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
# define SCxSR_ORER(port) SCIF_ORER
#else
# define SCxSR_ORER(port) 0x0000 # define SCxSR_ORER(port) 0x0000
#endif
# define SCxSR_FER(port) SCIF_FER # define SCxSR_FER(port) SCIF_FER
# define SCxSR_PER(port) SCIF_PER # define SCxSR_PER(port) SCIF_PER
# define SCxSR_BRK(port) SCIF_BRK # define SCxSR_BRK(port) SCIF_BRK
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
# define SCxSR_RDxF_CLEAR(port) (sci_in(port,SCxSR)&0xfffc)
# define SCxSR_ERROR_CLEAR(port) (sci_in(port,SCxSR)&0xfd73)
# define SCxSR_TDxE_CLEAR(port) (sci_in(port,SCxSR)&0xffdf)
# define SCxSR_BREAK_CLEAR(port) (sci_in(port,SCxSR)&0xffe3)
#else
# define SCxSR_RDxF_CLEAR(port) 0x00fc # define SCxSR_RDxF_CLEAR(port) 0x00fc
# define SCxSR_ERROR_CLEAR(port) 0x0073 # define SCxSR_ERROR_CLEAR(port) 0x0073
# define SCxSR_TDxE_CLEAR(port) 0x00df # define SCxSR_TDxE_CLEAR(port) 0x00df
# define SCxSR_BREAK_CLEAR(port) 0x00e3 # define SCxSR_BREAK_CLEAR(port) 0x00e3
#endif
#else #else
# define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) # define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
# define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) # define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
...@@ -171,6 +227,7 @@ ...@@ -171,6 +227,7 @@
/* SCFCR */ /* SCFCR */
#define SCFCR_RFRST 0x0002 #define SCFCR_RFRST 0x0002
#define SCFCR_TFRST 0x0004 #define SCFCR_TFRST 0x0004
#define SCFCR_TCRST 0x4000
#define SCFCR_MCE 0x0008 #define SCFCR_MCE 0x0008
#define SCI_MAJOR 204 #define SCI_MAJOR 204
...@@ -250,12 +307,17 @@ struct sci_port { ...@@ -250,12 +307,17 @@ struct sci_port {
} }
#ifdef CONFIG_CPU_SH3 #ifdef CONFIG_CPU_SH3
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#else
#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
h8_sci_offset, h8_sci_size) \ h8_sci_offset, h8_sci_size) \
CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size) CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size)
#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size) CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
#endif
#elif defined(__H8300H__) || defined(__H8300S__) #elif defined(__H8300H__) || defined(__H8300S__)
#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
...@@ -271,6 +333,19 @@ struct sci_port { ...@@ -271,6 +333,19 @@ struct sci_port {
CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
#endif #endif
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
SCIF_FNS(SCSCR, 0x08, 16)
SCIF_FNS(SCTDSR, 0x0c, 8)
SCIF_FNS(SCFER, 0x10, 16)
SCIF_FNS(SCxSR, 0x14, 16)
SCIF_FNS(SCFCR, 0x18, 16)
SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
SCIF_FNS(SCLSR, 0x24, 16)
#else
/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/
/* name off sz off sz off sz off sz off sz*/ /* name off sz off sz off sz off sz off sz*/
SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16, 0x00, 8) SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16, 0x00, 8)
...@@ -281,8 +356,9 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) ...@@ -281,8 +356,9 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x20, 16)
SCIF_FNS(SCLSR, 0, 0, 0x24, 16) SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
#endif
#define sci_in(port, reg) sci_##reg##_in(port) #define sci_in(port, reg) sci_##reg##_in(port)
#define sci_out(port, reg, value) sci_##reg##_out(port, value) #define sci_out(port, reg, value) sci_##reg##_out(port, value)
...@@ -369,6 +445,13 @@ static inline int sci_rxd_in(struct uart_port *port) ...@@ -369,6 +445,13 @@ static inline int sci_rxd_in(struct uart_port *port)
if (port->mapbase == 0xfe620000) if (port->mapbase == 0xfe620000)
return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
} }
#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
static inline int sci_rxd_in(struct uart_port *port)
{
if (port->mapbase == 0xa4430000)
return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCIF0 */
return 1;
}
#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port)
{ {
...@@ -378,6 +461,11 @@ static inline int sci_rxd_in(struct uart_port *port) ...@@ -378,6 +461,11 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
} }
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
static inline int sci_rxd_in(struct uart_port *port)
{
return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */
}
#elif defined(__H8300H__) || defined(__H8300S__) #elif defined(__H8300H__) || defined(__H8300S__)
static inline int sci_rxd_in(struct uart_port *port) static inline int sci_rxd_in(struct uart_port *port)
{ {
...@@ -420,7 +508,9 @@ static inline int sci_rxd_in(struct uart_port *port) ...@@ -420,7 +508,9 @@ static inline int sci_rxd_in(struct uart_port *port)
#define PCLK (current_cpu_data.module_clock) #define PCLK (current_cpu_data.module_clock)
#if !defined(__H8300H__) && !defined(__H8300S__) #if defined(CONFIG_CPU_SUBTYPE_SH7300)
#define SCBRR_VALUE(bps) ((PCLK+16*bps)/(16*bps)-1)
#elif !defined(__H8300H__) && !defined(__H8300S__)
#define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1) #define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1)
#else #else
#define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment