Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: scif.c,v 1.1 2011/03/03 05:59:37 kiyohara Exp $	*/
      2 /*
      3  * Copyright (c) 2011 KIYOHARA Takashi
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifdef CONS_SCIF
     29 
     30 #include <lib/libsa/stand.h>
     31 #include <lib/libkern/libkern.h>
     32 
     33 #include <sh3/scifreg.h>
     34 
     35 #include <machine/cpu.h>
     36 
     37 #include "boot.h"
     38 #include "scif.h"
     39 
     40 #define BOOT_PCLOCK	40000000
     41 
     42 #if defined(SH3) && defined(SH4)
     43 #error "mmeye port don't support SH3,SH4 common boot."
     44 #elif defined(SH3)
     45 #error "don't support SH3 common boot."
     46 #elif defined(SH4)
     47 #define CPU_IS_SH4	1
     48 #endif
     49 
     50 void *
     51 scif_init(int speed)
     52 {
     53 
     54 #define divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
     55 
     56 	/* Initialize SCR */
     57 	SHREG_SCSCR2 = 0x00;
     58 
     59 	SHREG_SCFCR2 = SCFCR2_TFRST | SCFCR2_RFRST;
     60 
     61 	/* Serial Mode Register */
     62 	SHREG_SCSMR2 = 0x00;	/* 8bit,NonParity,Even,1Stop */
     63 
     64 	/* Bit Rate Register */
     65 	SHREG_SCBRR2 = divrnd(BOOT_PCLOCK, 32 * speed) - 1;
     66 
     67 	/*
     68 	 * wait 2m Sec, because Send/Recv must begin 1 bit period after
     69 	 * BRR is set.
     70 	 */
     71 	delay(2000);
     72 
     73 	SHREG_SCFCR2 = FIFO_RCV_TRIGGER_14 | FIFO_XMT_TRIGGER_1;
     74 
     75 	/* Send permission, Receive permission ON */
     76 	SHREG_SCSCR2 = SCSCR2_TE | SCSCR2_RE;
     77 
     78 	/* Serial Status Register */
     79 	SHREG_SCSSR2 = (SHREG_SCSSR2 & SCSSR2_TDFE);	/* Clear Status */
     80 
     81 	return NULL;
     82 }
     83 
     84 void
     85 scif_putc(int c)
     86 {
     87 
     88 	/* wait for ready */
     89 	while ((SHREG_SCFDR2 & SCFDR2_TXCNT) == SCFDR2_TXF_FULL)
     90 		continue;
     91 
     92 	/* write send data to send register */
     93 	SHREG_SCFTDR2 = c;
     94 
     95 	/* clear ready flag */
     96 	SHREG_SCSSR2 = (SHREG_SCSSR2 & ~(SCSSR2_TDFE | SCSSR2_TEND));
     97 }
     98 
     99 int
    100 scif_getc(void)
    101 {
    102 	unsigned char c, err_c;
    103 #ifdef SH4
    104 	unsigned short err_c2 = 0;
    105 #endif
    106 
    107 	for (;;) {
    108 		/* wait for ready */
    109 		while ((SHREG_SCFDR2 & SCFDR2_RECVCNT) == 0)
    110 			continue;
    111 
    112 		c = SHREG_SCFRDR2;
    113 		err_c = SHREG_SCSSR2;
    114 		SHREG_SCSSR2 = (SHREG_SCSSR2 &
    115 		    ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_RDF | SCSSR2_DR));
    116 #ifdef SH4
    117 		if (CPU_IS_SH4) {
    118 			err_c2 = SHREG_SCLSR2;
    119 			SHREG_SCLSR2 = (SHREG_SCLSR2 & ~SCLSR2_ORER);
    120 		}
    121 #endif
    122 		if ((err_c &
    123 		    (SCSSR2_ER | SCSSR2_BRK | SCSSR2_FER | SCSSR2_PER)) == 0) {
    124 #ifdef SH4
    125 			if (CPU_IS_SH4 && ((err_c2 & SCLSR2_ORER) == 0))
    126 #endif
    127 				return c;
    128 		}
    129 	}
    130 }
    131 
    132 int
    133 scif_scankbd(void)
    134 {
    135 	unsigned char c, err_c;
    136 #ifdef SH4
    137 	unsigned short err_c2 = 0;
    138 #endif
    139 
    140 	for (;;) {
    141 		/* wait for ready */
    142 		if ((SHREG_SCFDR2 & SCFDR2_RECVCNT) == 0)
    143 			return -1;
    144 
    145 		c = SHREG_SCFRDR2;
    146 		err_c = SHREG_SCSSR2;
    147 		SHREG_SCSSR2 = (SHREG_SCSSR2 &
    148 		    ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_RDF | SCSSR2_DR));
    149 #ifdef SH4
    150 		if (CPU_IS_SH4) {
    151 			err_c2 = SHREG_SCLSR2;
    152 			SHREG_SCLSR2 = (SHREG_SCLSR2 & ~SCLSR2_ORER);
    153 		}
    154 #endif
    155 		if ((err_c &
    156 		    (SCSSR2_ER | SCSSR2_BRK | SCSSR2_FER | SCSSR2_PER)) == 0) {
    157 #ifdef SH4
    158 			if (CPU_IS_SH4 && ((err_c2 & SCLSR2_ORER) == 0))
    159 #endif
    160 				return c;
    161 		}
    162 	}
    163 }
    164 #endif /* CONS_SCIF */
    165