[U-Boot] [PATCH 4/5] standard SCI support
Yoshinori Sato
ysato at users.sourceforge.jp
Wed Mar 2 08:40:11 CET 2011
h8300 have simlar sh serial I/F.
It without FIFO.
This changes support of no FIFO.
Signed-off-by: Yoshinori Sato <ysato at users.sourceforge.jp>
---
drivers/serial/serial_sh.c | 74 +++++++++++++++++++++++++++++++---
drivers/serial/serial_sh.h | 93 +++++++++++++++-----------------------------
2 files changed, 98 insertions(+), 69 deletions(-)
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index fcf69ab..b6c800d 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -39,18 +39,73 @@
# error "Default SCIF doesn't set....."
#endif
-#if defined(CONFIG_SCIF_A)
- #define SCIF_BASE_PORT PORT_SCIFA
+#if defined(CONFIG_SCI)
+# define PORT_TYPE PORT_SCI
+#elif defined(CONFIG_SCIF_A)
+# define PORT_TYPE PORT_SCIFA
#else
- #define SCIF_BASE_PORT PORT_SCIF
+# define PORT_TYPE PORT_SCIF
#endif
static struct uart_port sh_sci = {
.membase = (unsigned char*)SCIF_BASE,
.mapbase = SCIF_BASE,
- .type = SCIF_BASE_PORT,
+ .type = PORT_TYPE,
};
+/* TDRE / RDRF emulation for RX610 */
+/* RX610's SCI don't have TDRE and RDRF in SSR
+ This part emulate these flags of IR */
+#if defined(CONFIG_CPU_RX610)
+
+#define port_to_irq(port) ((((port)->mapbase - 0x88240) / 8) + 214)
+#define read_ir(irq) __raw_readb((unsigned char *)(0x00087000 + (irq)))
+#define clear_ir(irq) __raw_writeb(0, (unsigned char *)(0x00087000 + (irq)))
+
+#define write_ier(flg, irq) \
+do { \
+ unsigned char ier = __raw_readb((unsigned char *)(0x00087200 + ((irq) >> 3))); \
+ ier &= ~(1 << ((irq) & 7)); \
+ if (flg) \
+ ier |= (1 << ((irq) & 7)); \
+ __raw_writeb(ier, (unsigned char *)(0x00087200 + ((irq) >> 3))); \
+} while(0)
+
+
+static unsigned int sci_SCxSR_in(struct uart_port *port)
+{
+ int irq = port_to_irq(port);
+ unsigned char ssr;
+ ssr = __raw_readb(port->membase + 4);
+ ssr &= ~0xc0;
+ /* map to RXI -> RDRF and TXI -> TDRE */
+ ssr |= read_ir(irq + 1) << 6 | read_ir(irq + 2) << 7;
+ return ssr;
+}
+
+static void sci_SCxSR_out(struct uart_port *port, unsigned int value)
+{
+ int irq = port_to_irq(port);
+ /* clear ir */
+ if ((value & 0x84) != 0x84)
+ clear_ir(irq + 2);
+ if ((value & 0x40) == 0)
+ clear_ir(irq + 1);
+ value |= 0xc0; /* b7 and b6 is always 1 */
+ value &= ~0x01; /* b0 is always 0 */
+ __raw_writeb(value, port->membase + 4);
+}
+
+static void sci_SCSCR_out(struct uart_port *port, unsigned int value)
+{
+ int irq = port_to_irq(port);
+ write_ier(value & 0x40, irq + 1);
+ write_ier(value & 0x80, irq + 2);
+ /* TXI and RXI always enabled */
+ __raw_writeb(value | 0xc0, port->membase + 2);
+}
+#endif
+
void serial_setbrg(void)
{
DECLARE_GLOBAL_DATA_PTR;
@@ -99,6 +154,11 @@ static int scif_rxfill(struct uart_port *port)
else
return sci_in(port, SCRFDR);
}
+#elif defined(CONFIG_SCI)
+static int scif_rxfill(struct uart_port *port)
+{
+ return (sci_in(port, SCxSR) & SCxSR_RDxF(port))?1:0;
+}
#else
static int scif_rxfill(struct uart_port *port)
{
@@ -115,12 +175,12 @@ void serial_raw_putc(const char c)
{
while (1) {
/* Tx fifo is empty */
- if (sci_in(&sh_sci, SCxSR) & SCxSR_TEND(&sh_sci))
+ if (sci_in(&sh_sci, SCxSR) & SCxSR_TXRDY(&sh_sci))
break;
}
sci_out(&sh_sci, SCxTDR, c);
- sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TEND(&sh_sci));
+ sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TXRDY(&sh_sci));
}
void serial_putc(const char c)
@@ -156,7 +216,7 @@ int serial_getc_check(void)
status = sci_in(&sh_sci, SCxSR);
- if (status & SCIF_ERRORS)
+ if (status & SCxSR_ERRORS(&sh_sci))
handle_error();
if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci))
handle_error();
diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h
index e19593c..069aa36 100644
--- a/drivers/serial/serial_sh.h
+++ b/drivers/serial/serial_sh.h
@@ -14,13 +14,6 @@ struct uart_port {
#define PORT_SCIFA 83
#define PORT_SCIFB 93
-#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
-#include <asm/regs306x.h>
-#endif
-#if defined(CONFIG_H8S2678)
-#include <asm/regs267x.h>
-#endif
-
#if defined(CONFIG_CPU_SH7706) || \
defined(CONFIG_CPU_SH7707) || \
defined(CONFIG_CPU_SH7708) || \
@@ -126,12 +119,20 @@ struct uart_port {
# 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 */
-#elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
+#elif defined(CONFIG_CPU_H83007) || \
+ defined(CONFIG_CPU_H83068) || \
+ defined(CONFIG_CPU_H83069)
# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
# define H8300_SCI_DR(ch) (*(volatile char *)(P1DR + h8300_sci_pins[ch].port))
-#elif defined(CONFIG_H8S2678)
+# define SCIF0_BASE 0xffffb0
+# define SCIF1_BASE 0xffffb8
+# define SCIF2_BASE 0xffffc0
+#elif defined(CONFIG_CPU_H8S2678)
# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
# define H8300_SCI_DR(ch) (*(volatile char *)(P1DR + h8300_sci_pins[ch].port))
+# define SCIF0_BASE 0xffff78
+# define SCIF1_BASE 0xffff80
+# define SCIF2_BASE 0xffff88
#elif defined(CONFIG_CPU_SH7757)
# define SCSPTR0 0xfe4b0020
# define SCSPTR1 0xfe4b0020
@@ -202,6 +203,15 @@ struct uart_port {
# define SCSPTR3 0xffc60020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+#elif defined(CONFIG_RX)
+# define SCSPTR0 0x00088240 /* 8 bit SCI */
+# define SCSPTR1 0x00088248 /* 8 bit SCI */
+# define SCSPTR2 0x00088250 /* 8 bit SCI */
+# define SCSPTR3 0x00088258 /* 8 bit SCI */
+# define SCSPTR4 0x00088260 /* 8 bit SCI */
+# define SCSPTR5 0x00088268 /* 8 bit SCI */
+# define SCSPTR6 0x00088270 /* 8 bit SCI */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#else
# error CPU subtype not defined
#endif
@@ -299,6 +309,8 @@ struct uart_port {
((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
#define SCxSR_ORER(port)\
(((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER)
+#define SCxSR_TXRDY(port)\
+ (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TEND)
#if defined(CONFIG_CPU_SH7705) || \
defined(CONFIG_CPU_SH7720) || \
@@ -369,7 +381,7 @@ static inline void sci_##name##_out(struct uart_port *port,\
#ifdef CONFIG_H8300
/* h8300 don't have SCIF */
-#define CPU_SCIF_FNS(name) \
+#define CPU_SCIF_FNS(name, scif_offset, scif_size) \
static inline unsigned int sci_##name##_in(struct uart_port *port) {\
return 0;\
}\
@@ -437,7 +449,7 @@ static inline void sci_##name##_out(struct uart_port *port,\
sh4_scif_offset, sh4_scif_size) \
CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
#endif
-#elif defined(__H8300H__) || defined(__H8300S__)
+#elif defined(CONFIG_H8300) || defined(CONFIG_RX)
#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size,\
sh4_sci_offset, sh4_sci_size, \
sh3_scif_offset, sh3_scif_size,\
@@ -446,7 +458,7 @@ static inline void sci_##name##_out(struct uart_port *port,\
CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size)
#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size,\
sh4_scif_offset, sh4_scif_size) \
- CPU_SCIF_FNS(name)
+ CPU_SCIF_FNS(name, 0, 0)
#elif defined(CONFIG_CPU_SH7723) || defined(CONFIG_CPU_SH7724)
#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size,\
sh4_scif_offset, sh4_scif_size) \
@@ -512,6 +524,13 @@ SCIF_FNS(SCFER, 0x10, 16)
SCIF_FNS(SCFCR, 0x18, 16)
SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCLSR, 0x24, 16)
+#elif defined(CONFIG_CPU_RX610)
+SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16, 0x00, 8)
+SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8, 0x01, 8)
+SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8)
+SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
+SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
+SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
#else
/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/
/* name off sz off sz off sz off sz off sz*/
@@ -552,48 +571,6 @@ SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
#define sci_in(port, reg) sci_##reg##_in(port)
#define sci_out(port, reg, value) sci_##reg##_out(port, value)
-/* H8/300 series SCI pins assignment */
-#if defined(__H8300H__) || defined(__H8300S__)
-static const struct __attribute__((packed)) {
- int port; /* GPIO port no */
- unsigned short rx, tx; /* GPIO bit no */
-} h8300_sci_pins[] = {
-#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
- { /* SCI0 */
- .port = H8300_GPIO_P9,
- .rx = H8300_GPIO_B2,
- .tx = H8300_GPIO_B0,
- },
- { /* SCI1 */
- .port = H8300_GPIO_P9,
- .rx = H8300_GPIO_B3,
- .tx = H8300_GPIO_B1,
- },
- { /* SCI2 */
- .port = H8300_GPIO_PB,
- .rx = H8300_GPIO_B7,
- .tx = H8300_GPIO_B6,
- }
-#elif defined(CONFIG_H8S2678)
- { /* SCI0 */
- .port = H8300_GPIO_P3,
- .rx = H8300_GPIO_B2,
- .tx = H8300_GPIO_B0,
- },
- { /* SCI1 */
- .port = H8300_GPIO_P3,
- .rx = H8300_GPIO_B3,
- .tx = H8300_GPIO_B1,
- },
- { /* SCI2 */
- .port = H8300_GPIO_P5,
- .rx = H8300_GPIO_B1,
- .tx = H8300_GPIO_B0,
- }
-#endif
-};
-#endif
-
#if defined(CONFIG_CPU_SH7706) || \
defined(CONFIG_CPU_SH7707) || \
defined(CONFIG_CPU_SH7708) || \
@@ -616,12 +593,6 @@ static inline int sci_rxd_in(struct uart_port *port)
return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */
return 1;
}
-#elif defined(__H8300H__) || defined(__H8300S__)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- int ch = (port->mapbase - SMR0) >> 3;
- return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0;
-}
#else /* default case for non-SCI processors */
static inline int sci_rxd_in(struct uart_port *port)
{
@@ -683,8 +654,6 @@ static inline int scbrr_calc(struct uart_port port, int bps, int clk)
return ((clk*2)+16*bps)/(16*bps)-1;
}
#define SCBRR_VALUE(bps, clk) scbrr_calc(sh_sci, bps, clk)
-#elif defined(__H8300H__) || defined(__H8300S__)
-#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
#else /* Generic SH */
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
#endif
--
1.7.2.3
More information about the U-Boot
mailing list