mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 03:58:17 +00:00 
			
		
		
		
	So far the console API uses the following naming convention: ======Extract====== typedef struct device_t; int device_register (device_t * dev); int devices_init (void); int device_deregister(char *devname); struct list_head* device_get_list(void); device_t* device_get_by_name(char* name); device_t* device_clone(device_t *dev); ======= which is too generic and confusing. Instead of using device_XX and device_t we change this into stdio_XX and stdio_dev This will also allow to add later a generic device mechanism in order to have support for multiple devices and driver instances. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Edited commit message. Signed-off-by: Wolfgang Denk <wd@denx.de>
		
			
				
	
	
		
			270 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * (C) Copyright 2000
 | |
|  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 | |
|  *
 | |
|  * 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
 | |
|  */
 | |
| 
 | |
| /* Modified by Udi Finkelstein
 | |
|  *
 | |
|  * This file includes communication routines for SMC1 that can run even if
 | |
|  * SMC2 have already been initialized.
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <watchdog.h>
 | |
| #include <commproc.h>
 | |
| #include <stdio_dev.h>
 | |
| #include <lcd.h>
 | |
| 
 | |
| DECLARE_GLOBAL_DATA_PTR;
 | |
| 
 | |
| #define	SMC_INDEX	0
 | |
| #define PROFF_SMC	PROFF_SMC1
 | |
| #define CPM_CR_CH_SMC	CPM_CR_CH_SMC1
 | |
| 
 | |
| #define RBC823_KBD_BAUDRATE	38400
 | |
| #define CPM_KEYBOARD_BASE	0x1000
 | |
| /*
 | |
|  * Minimal serial functions needed to use one of the SMC ports
 | |
|  * as serial console interface.
 | |
|  */
 | |
| 
 | |
| void smc1_setbrg (void)
 | |
| {
 | |
| 	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
 | |
| 	volatile cpm8xx_t *cp = &(im->im_cpm);
 | |
| 
 | |
| 	/* Set up the baud rate generator.
 | |
| 	 * See 8xx_io/commproc.c for details.
 | |
| 	 *
 | |
| 	 * Wire BRG2 to SMC1, BRG1 to SMC2
 | |
| 	 */
 | |
| 
 | |
| 	cp->cp_simode = 0x00001000;
 | |
| 
 | |
| 	cp->cp_brgc2 =
 | |
| 		(((gd->cpu_clk / 16 / RBC823_KBD_BAUDRATE)-1) << 1) | CPM_BRG_EN;
 | |
| }
 | |
| 
 | |
| int smc1_init (void)
 | |
| {
 | |
| 	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
 | |
| 	volatile smc_t *sp;
 | |
| 	volatile smc_uart_t *up;
 | |
| 	volatile cbd_t *tbdf, *rbdf;
 | |
| 	volatile cpm8xx_t *cp = &(im->im_cpm);
 | |
| 	uint	dpaddr;
 | |
| 
 | |
| 	/* initialize pointers to SMC */
 | |
| 
 | |
| 	sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]);
 | |
| 	up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC];
 | |
| 
 | |
| 	/* Disable transmitter/receiver.
 | |
| 	*/
 | |
| 	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
 | |
| 
 | |
| 	/* Enable SDMA.
 | |
| 	*/
 | |
| 	im->im_siu_conf.sc_sdcr = 1;
 | |
| 
 | |
| 	/* clear error conditions */
 | |
| #ifdef	CONFIG_SYS_SDSR
 | |
| 	im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR;
 | |
| #else
 | |
| 	im->im_sdma.sdma_sdsr = 0x83;
 | |
| #endif
 | |
| 
 | |
| 	/* clear SDMA interrupt mask */
 | |
| #ifdef	CONFIG_SYS_SDMR
 | |
| 	im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR;
 | |
| #else
 | |
| 	im->im_sdma.sdma_sdmr = 0x00;
 | |
| #endif
 | |
| 
 | |
| 	/* Use Port B for SMC1 instead of other functions.
 | |
| 	*/
 | |
| 	cp->cp_pbpar |=  0x000000c0;
 | |
| 	cp->cp_pbdir &= ~0x000000c0;
 | |
| 	cp->cp_pbodr &= ~0x000000c0;
 | |
| 
 | |
| 	/* Set the physical address of the host memory buffers in
 | |
| 	 * the buffer descriptors.
 | |
| 	 */
 | |
| 
 | |
| #ifdef CONFIG_SYS_ALLOC_DPRAM
 | |
| 	dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
 | |
| #else
 | |
| 	dpaddr = CPM_KEYBOARD_BASE ;
 | |
| #endif
 | |
| 
 | |
| 	/* Allocate space for two buffer descriptors in the DP ram.
 | |
| 	 * For now, this address seems OK, but it may have to
 | |
| 	 * change with newer versions of the firmware.
 | |
| 	 * damm: allocating space after the two buffers for rx/tx data
 | |
| 	 */
 | |
| 
 | |
| 	rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
 | |
| 	rbdf->cbd_bufaddr = (uint) (rbdf+2);
 | |
| 	rbdf->cbd_sc = 0;
 | |
| 	tbdf = rbdf + 1;
 | |
| 	tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
 | |
| 	tbdf->cbd_sc = 0;
 | |
| 
 | |
| 	/* Set up the uart parameters in the parameter ram.
 | |
| 	*/
 | |
| 	up->smc_rbase = dpaddr;
 | |
| 	up->smc_tbase = dpaddr+sizeof(cbd_t);
 | |
| 	up->smc_rfcr = SMC_EB;
 | |
| 	up->smc_tfcr = SMC_EB;
 | |
| 
 | |
| 	/* Set UART mode, 8 bit, no parity, one stop.
 | |
| 	 * Enable receive and transmit.
 | |
| 	 */
 | |
| 	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
 | |
| 
 | |
| 	/* Mask all interrupts and remove anything pending.
 | |
| 	*/
 | |
| 	sp->smc_smcm = 0;
 | |
| 	sp->smc_smce = 0xff;
 | |
| 
 | |
| 	/* Set up the baud rate generator.
 | |
| 	*/
 | |
| 	smc1_setbrg ();
 | |
| 
 | |
| 	/* Make the first buffer the only buffer.
 | |
| 	*/
 | |
| 	tbdf->cbd_sc |= BD_SC_WRAP;
 | |
| 	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
 | |
| 
 | |
| 	/* Single character receive.
 | |
| 	*/
 | |
| 	up->smc_mrblr = 1;
 | |
| 	up->smc_maxidl = 0;
 | |
| 
 | |
| 	/* Initialize Tx/Rx parameters.
 | |
| 	*/
 | |
| 
 | |
| 	while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
 | |
| 	  ;
 | |
| 
 | |
| 	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
 | |
| 
 | |
| 	while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
 | |
| 	  ;
 | |
| 
 | |
| 	/* Enable transmitter/receiver.
 | |
| 	*/
 | |
| 	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
 | |
| 
 | |
| 	return (0);
 | |
| }
 | |
| 
 | |
| void smc1_putc(const char c)
 | |
| {
 | |
| 	volatile cbd_t		*tbdf;
 | |
| 	volatile char		*buf;
 | |
| 	volatile smc_uart_t	*up;
 | |
| 	volatile immap_t	*im = (immap_t *)CONFIG_SYS_IMMR;
 | |
| 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 | |
| 
 | |
| 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 | |
| 
 | |
| 	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
 | |
| 
 | |
| 	/* Wait for last character to go.
 | |
| 	*/
 | |
| 
 | |
| 	buf = (char *)tbdf->cbd_bufaddr;
 | |
| 
 | |
| 	*buf = c;
 | |
| 	tbdf->cbd_datlen = 1;
 | |
| 	tbdf->cbd_sc |= BD_SC_READY;
 | |
| 	__asm__("eieio");
 | |
| 
 | |
| 	while (tbdf->cbd_sc & BD_SC_READY) {
 | |
| 		WATCHDOG_RESET ();
 | |
| 		__asm__("eieio");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int smc1_getc(void)
 | |
| {
 | |
| 	volatile cbd_t		*rbdf;
 | |
| 	volatile unsigned char	*buf;
 | |
| 	volatile smc_uart_t	*up;
 | |
| 	volatile immap_t	*im = (immap_t *)CONFIG_SYS_IMMR;
 | |
| 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 | |
| 	unsigned char		c;
 | |
| 
 | |
| 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 | |
| 
 | |
| 	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
 | |
| 
 | |
| 	/* Wait for character to show up.
 | |
| 	*/
 | |
| 	buf = (unsigned char *)rbdf->cbd_bufaddr;
 | |
| 
 | |
| 	while (rbdf->cbd_sc & BD_SC_EMPTY)
 | |
| 		WATCHDOG_RESET ();
 | |
| 
 | |
| 	c = *buf;
 | |
| 	rbdf->cbd_sc |= BD_SC_EMPTY;
 | |
| 
 | |
| 	return(c);
 | |
| }
 | |
| 
 | |
| int smc1_tstc(void)
 | |
| {
 | |
| 	volatile cbd_t		*rbdf;
 | |
| 	volatile smc_uart_t	*up;
 | |
| 	volatile immap_t	*im = (immap_t *)CONFIG_SYS_IMMR;
 | |
| 	volatile cpm8xx_t	*cpmp = &(im->im_cpm);
 | |
| 
 | |
| 	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 | |
| 
 | |
| 	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
 | |
| 
 | |
| 	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
 | |
| }
 | |
| 
 | |
| /* search for keyboard and register it if found */
 | |
| int drv_keyboard_init(void)
 | |
| {
 | |
| 	int error = 0;
 | |
| 	struct stdio_dev kbd_dev;
 | |
| 
 | |
| 	if (0) {
 | |
| 		/* register the keyboard */
 | |
| 		memset (&kbd_dev, 0, sizeof(struct stdio_dev));
 | |
| 		strcpy(kbd_dev.name, "kbd");
 | |
| 		kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
 | |
| 		kbd_dev.putc = NULL;
 | |
| 		kbd_dev.puts = NULL;
 | |
| 		kbd_dev.getc = smc1_getc;
 | |
| 		kbd_dev.tstc = smc1_tstc;
 | |
| 		error = stdio_register (&kbd_dev);
 | |
| 	} else {
 | |
| 		lcd_is_enabled = 0;
 | |
| 		lcd_disable();
 | |
| 	}
 | |
| 	return error;
 | |
| }
 |