diff options
| author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2011-02-24 07:41:10 +0000 | 
|---|---|---|
| committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2011-02-24 07:41:10 +0000 | 
| commit | f40a767b0d5c43234a6e026c48e1c59fa1980963 (patch) | |
| tree | f4b2252c206039808ad9c54fbe62bb8419d4ec22 /package/uboot-lantiq/files/cpu/mips/ifx_asc.c | |
| parent | ec4b08c1c100022f22b8f897d79d003e11c3c254 (diff) | |
[uboot-lantiq]
* adds stage1 lzma
* new boards
* fixes settings for PSC ram
* lost of cleanups
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@25694 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/uboot-lantiq/files/cpu/mips/ifx_asc.c')
| -rw-r--r-- | package/uboot-lantiq/files/cpu/mips/ifx_asc.c | 218 | 
1 files changed, 218 insertions, 0 deletions
diff --git a/package/uboot-lantiq/files/cpu/mips/ifx_asc.c b/package/uboot-lantiq/files/cpu/mips/ifx_asc.c new file mode 100644 index 000000000..5c13f2662 --- /dev/null +++ b/package/uboot-lantiq/files/cpu/mips/ifx_asc.c @@ -0,0 +1,218 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * (C) Copyright 2009 + * Infineon Technologies AG, http://www.infineon.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/addrspace.h> + +#include "ifx_asc.h" + +#define SET_BIT(reg, mask)			asc_writel(reg, asc_readl(reg) | (mask)) +#define CLEAR_BIT(reg, mask)			asc_writel(reg, asc_readl(reg) & (~mask)) +#define SET_BITFIELD(reg, mask, off, val)	asc_writel(reg, (asc_readl(reg) & (~mask)) | (val << off) ) + +#undef DEBUG_ASC_RAW +#ifdef DEBUG_ASC_RAW +#define DEBUG_ASC_RAW_RX_BUF			0xA0800000 +#define DEBUG_ASC_RAW_TX_BUF			0xA0900000 +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static IfxAsc_t *pAsc = (IfxAsc_t *)CKSEG1ADDR(CONFIG_SYS_IFX_ASC_BASE); + +/* + *             FDV            fASC + * BaudRate = ----- * -------------------- + *             512    16 * (ReloadValue+1) + */ + +/* + *                  FDV          fASC + * ReloadValue = ( ----- * --------------- ) - 1 + *                  512     16 * BaudRate + */ +static void serial_divs(u32 baudrate, u32 fasc, u32 *pfdv, u32 *preload) +{ +   u32 clock = fasc / 16; + +   u32 fdv; /* best fdv */ +   u32 reload = 0; /* best reload */ +   u32 diff; /* smallest diff */ +   u32 idiff; /* current diff */ +   u32 ireload; /* current reload */ +   u32 i; /* current fdv */ +   u32 result; /* current resulting baudrate */ + +   if (clock > 0x7FFFFF) +      clock /= 512; +   else +      baudrate *= 512; + +   fdv = 512; /* start with 1:1 fraction */ +   diff = baudrate; /* highest possible */ + +   /* i is the test fdv value -- start with the largest possible */ +   for (i = 512; i > 0; i--) +   { +      ireload = (clock * i) / baudrate; +      if (ireload < 1) +         break; /* already invalid */ +      result = (clock * i) / ireload; + +      idiff = (result > baudrate) ? (result - baudrate) : (baudrate - result); +      if (idiff == 0) +      { +         fdv = i; +         reload = ireload; +         break; /* can't do better */ +      } +      else if (idiff < diff) +      { +         fdv = i; /* best so far */ +         reload = ireload; +         diff = idiff; /* update lowest diff*/ +      } +   } + +   *pfdv = (fdv == 512) ? 0 : fdv; +   *preload = reload - 1; +} + + +void serial_setbrg (void) +{ +	u32 ReloadValue, fdv; + +	serial_divs(gd->baudrate, get_bus_freq(0), &fdv, &ReloadValue); + +	/* Disable Baud Rate Generator; BG should only be written when R=0 */ +	CLEAR_BIT(asc_con, ASCCON_R); + +	/* Enable Fractional Divider */ +	SET_BIT(asc_con, ASCCON_FDE);	/* FDE = 1 */ + +	/* Set fractional divider value */ +	asc_writel(asc_fdv, fdv & ASCFDV_VALUE_MASK); + +	/* Set reload value in BG */ +	asc_writel(asc_bg, ReloadValue); + +	/* Enable Baud Rate Generator */ +	SET_BIT(asc_con, ASCCON_R);	/* R = 1 */ +} + + +int serial_init (void) +{ + +	/* and we have to set CLC register*/ +	CLEAR_BIT(asc_clc, ASCCLC_DISS); +	SET_BITFIELD(asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001); + +	/* initialy we are in async mode */ +	asc_writel(asc_con, ASCCON_M_8ASYNC); + +	/* select input port */ +	asc_writel(asc_pisel, CONSOLE_TTY & 0x1); + +	/* TXFIFO's filling level */ +	SET_BITFIELD(asc_txfcon, ASCTXFCON_TXFITLMASK, +			ASCTXFCON_TXFITLOFF, ASC_TXFIFO_FL); +	/* enable TXFIFO */ +	SET_BIT(asc_txfcon, ASCTXFCON_TXFEN); + +	/* RXFIFO's filling level */ +	SET_BITFIELD(asc_txfcon, ASCRXFCON_RXFITLMASK, +			ASCRXFCON_RXFITLOFF, ASC_RXFIFO_FL); +	/* enable RXFIFO */ +	SET_BIT(asc_rxfcon, ASCRXFCON_RXFEN); + +	/* set baud rate */ +	serial_setbrg(); + +	/* enable error signals &  Receiver enable  */ +	SET_BIT(asc_whbstate, ASCWHBSTATE_SETREN|ASCCON_FEN|ASCCON_TOEN|ASCCON_ROEN); + +	return 0; +} + + +void serial_putc (const char c) +{ +	u32 txFl = 0; +#ifdef DEBUG_ASC_RAW +	static u8 * debug = (u8 *) DEBUG_ASC_RAW_TX_BUF; +	*debug++=c; +#endif +	if (c == '\n') +		serial_putc ('\r'); +	/* check do we have a free space in the TX FIFO */ +	/* get current filling level */ +	do { +		txFl = ( asc_readl(asc_fstat) & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF; +	} +	while ( txFl == ASC_TXFIFO_FULL ); + +	asc_writel(asc_tbuf, c); /* write char to Transmit Buffer Register */ + +	/* check for errors */ +	if ( asc_readl(asc_state) & ASCSTATE_TOE ) { +		SET_BIT(asc_whbstate, ASCWHBSTATE_CLRTOE); +		return; +	} +} + +void serial_puts (const char *s) +{ +	while (*s) { +		serial_putc (*s++); +	} +} + +int serial_getc (void) +{ +	char c; +	while ((asc_readl(asc_fstat) & ASCFSTAT_RXFFLMASK) == 0 ); +	c = (char)(asc_readl(asc_rbuf) & 0xff); + +#ifdef 	DEBUG_ASC_RAW +	static u8* debug=(u8*)(DEBUG_ASC_RAW_RX_BUF); +	*debug++=c; +#endif +	return c; +} + + +int serial_tstc (void) +{ +	int res = 1; + +	if ( (asc_readl(asc_fstat) & ASCFSTAT_RXFFLMASK) == 0 ) { +		res = 0; +	} +	return res; +}  | 
