diff mbox

[U-Boot,4/5] standard SCI support

Message ID 87tyfm9dic.wl%ysato@users.sourceforge.jp
State Changes Requested
Headers show

Commit Message

Yoshinori Sato March 2, 2011, 7:40 a.m. UTC
h8300 have simlar sh serial I/F.
It without FIFO.
This changes support of no FIFO.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 drivers/serial/serial_sh.c |   74 +++++++++++++++++++++++++++++++---
 drivers/serial/serial_sh.h |   93 +++++++++++++++-----------------------------
 2 files changed, 98 insertions(+), 69 deletions(-)

Comments

Nobuhiro Iwamatsu March 7, 2011, 1:21 a.m. UTC | #1
Hi,

2011/3/2 Yoshinori Sato <ysato@users.sourceforge.jp>:
> h8300 have simlar sh serial I/F.
> It without FIFO.
> This changes support of no FIFO.
>
> Signed-off-by: Yoshinori Sato <ysato@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)
> +

<snip>

> +#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

<snip>


> @@ -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,\

<snip>

> @@ -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)

Why do you use CPU_RX610 and CONFIG_RX ?
Is these necessary for support of H8300 support?

Best regards,
  Nobuhiro
diff mbox

Patch

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