⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpc52xx_tty.c

📁 linux内核源码
💻 C
字号:
/* * Minimal serial functions needed to send messages out a MPC52xx * Programmable Serial Controller (PSC). * * Author: Dale Farnsworth <dfarnsworth@mvista.com> * * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under the * terms of the GNU General Public License version 2.  This program is licensed * "as is" without any warranty of any kind, whether express or implied. */#include <linux/types.h>#include <asm/uaccess.h>#include <asm/mpc52xx.h>#include <asm/mpc52xx_psc.h>#include <asm/serial.h>#include <asm/io.h>#include <asm/time.h>#ifdef MPC52xx_PF_CONSOLE_PORT#define MPC52xx_CONSOLE MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT)#define MPC52xx_PSC_CONFIG_SHIFT ((MPC52xx_PF_CONSOLE_PORT-1)<<2)#else#error "MPC52xx_PF_CONSOLE_PORT not defined"#endifstatic struct mpc52xx_psc __iomem *psc =	(struct mpc52xx_psc __iomem *) MPC52xx_PA(MPC52xx_CONSOLE);/* The decrementer counts at the system bus clock frequency * divided by four.  The most accurate time base is connected to the * rtc.  We read the decrementer change during one rtc tick * and multiply by 4 to get the system bus clock frequency. Since a * rtc tick is one seconds, and that's pretty long, we change the rtc * dividers temporarily to set them 64x faster ;) */static intmpc52xx_ipbfreq(void){	struct mpc52xx_rtc __iomem *rtc =		(struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET);	struct mpc52xx_cdm __iomem *cdm =		(struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET);	int current_time, previous_time;	int tbl_start, tbl_end;	int xlbfreq, ipbfreq;	out_be32(&rtc->dividers, 0x8f1f0000);	/* Set RTC 64x faster */	previous_time = in_be32(&rtc->time);	while ((current_time = in_be32(&rtc->time)) == previous_time) ;	tbl_start = get_tbl();	previous_time = current_time;	while ((current_time = in_be32(&rtc->time)) == previous_time) ;	tbl_end = get_tbl();	out_be32(&rtc->dividers, 0xffff0000);   /* Restore RTC */	xlbfreq = (tbl_end - tbl_start) << 8;	ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq;	return ipbfreq;}unsigned longserial_init(int ignored, void *ignored2){	struct mpc52xx_gpio __iomem *gpio =		(struct mpc52xx_gpio __iomem *) MPC52xx_PA(MPC52xx_GPIO_OFFSET);	int divisor;	int mode1;	int mode2;	u32 val32;	static int been_here = 0;	if (been_here)		return 0;	been_here = 1;	val32 = in_be32(&gpio->port_config);	val32 &= ~(0x7 << MPC52xx_PSC_CONFIG_SHIFT);	val32 |= MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD				<< MPC52xx_PSC_CONFIG_SHIFT;	out_be32(&gpio->port_config, val32);	out_8(&psc->command, MPC52xx_PSC_RST_TX			| MPC52xx_PSC_RX_DISABLE | MPC52xx_PSC_TX_ENABLE);	out_8(&psc->command, MPC52xx_PSC_RST_RX);	out_be32(&psc->sicr, 0x0);	out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);	out_be16(&psc->tfalarm, 0xf8);	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1			| MPC52xx_PSC_RX_ENABLE			| MPC52xx_PSC_TX_ENABLE);	divisor = ((mpc52xx_ipbfreq()			/ (CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD * 16)) + 1) >> 1;	mode1 = MPC52xx_PSC_MODE_8_BITS | MPC52xx_PSC_MODE_PARNONE			| MPC52xx_PSC_MODE_ERR;	mode2 = MPC52xx_PSC_MODE_ONE_STOP;	out_8(&psc->ctur, divisor>>8);	out_8(&psc->ctlr, divisor);	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);	out_8(&psc->mode, mode1);	out_8(&psc->mode, mode2);	return 0;	/* ignored */}voidserial_putc(void *ignored, const char c){	serial_init(0, NULL);	while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ;	out_8(&psc->mpc52xx_psc_buffer_8, c);	while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ;}charserial_getc(void *ignored){	while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY)) ;	return in_8(&psc->mpc52xx_psc_buffer_8);}intserial_tstc(void *ignored){	return (in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY) != 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -