Viewing file: m8260_tty.c (7.12 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* * BK Id: SCCS/s.m8260_tty.c 1.7 05/18/01 07:54:04 patch */
/* Minimal serial functions needed to send messages out the serial * port on SMC1. */ #include <linux/types.h> #include <asm/mpc8260.h> #include <asm/cpm_8260.h>
uint no_print; extern char *params[]; extern int nparams; static u_char cons_hold[128], *sgptr; static int cons_hold_cnt;
/* If defined, enables serial console. The value (1 through 4) * should designate which SCC is used, but this isn't complete. Only * SCC1 is known to work at this time. */ #ifdef CONFIG_SCC_CONSOLE #define SCC_CONSOLE 1 #endif
void serial_init(bd_t *bd) { volatile smc_t *sp; volatile smc_uart_t *up; volatile scc_t *sccp; volatile scc_uart_t *sup; volatile cbd_t *tbdf, *rbdf; volatile immap_t *ip; volatile iop8260_t *io; volatile cpm8260_t *cp; uint dpaddr, memaddr;
ip = (immap_t *)IMAP_ADDR; cp = &ip->im_cpm; io = &ip->im_ioport;
/* Perform a reset. */ cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
/* Wait for it. */ while (cp->cp_cpcr & CPM_CR_FLG);
#ifdef CONFIG_ADS8260 /* Enable the RS-232 transceivers. */ *(volatile uint *)(BCSR_ADDR + 4) &= ~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2); #endif
#ifdef SCC_CONSOLE sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]); sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
/* Use Port D for SCC1 instead of other functions. */ io->iop_ppard |= 0x00000003; io->iop_psord &= ~0x00000001; /* Rx */ io->iop_psord |= 0x00000002; /* Tx */ io->iop_pdird &= ~0x00000001; /* Rx */ io->iop_pdird |= 0x00000002; /* Tx */
#else sp = (smc_t*)&(ip->im_smc[0]); *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
/* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
/* Use Port D for SMC1 instead of other functions. */ io->iop_ppard |= 0x00c00000; io->iop_pdird |= 0x00400000; io->iop_pdird &= ~0x00800000; io->iop_psord &= ~0x00c00000; #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. */ dpaddr = 0x0800;
/* Grab a few bytes from the top of memory. */ memaddr = (bd->bi_memsize - 256) & ~15;
/* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&ip->im_dprambase[dpaddr]; rbdf->cbd_bufaddr = memaddr; rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = memaddr+128; tbdf->cbd_sc = 0;
/* Set up the uart parameters in the parameter ram. */ #ifdef SCC_CONSOLE sup->scc_genscc.scc_rbase = dpaddr; sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t);
/* Set up the uart parameters in the * parameter ram. */ sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;
sup->scc_genscc.scc_mrblr = 128; sup->scc_maxidl = 8; sup->scc_brkcr = 1; sup->scc_parec = 0; sup->scc_frmec = 0; sup->scc_nosec = 0; sup->scc_brkec = 0; sup->scc_uaddr1 = 0; sup->scc_uaddr2 = 0; sup->scc_toseq = 0; sup->scc_char1 = 0x8000; sup->scc_char2 = 0x8000; sup->scc_char3 = 0x8000; sup->scc_char4 = 0x8000; sup->scc_char5 = 0x8000; sup->scc_char6 = 0x8000; sup->scc_char7 = 0x8000; sup->scc_char8 = 0x8000; sup->scc_rccm = 0xc0ff;
/* Send the CPM an initialize command. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG);
/* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sccp->scc_gsmrh = 0; sccp->scc_gsmrl = (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
/* Disable all interrupts and clear all pending * events. */ sccp->scc_sccm = 0; sccp->scc_scce = 0xffff; sccp->scc_dsr = 0x7e7e; sccp->scc_pmsr = 0x3000;
/* Wire BRG1 to SCC1. The console driver will take care of * others. */ ip->im_cpmux.cmx_scr = 0; #else up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = CPMFCR_EB; up->smc_tfcr = CPMFCR_EB; up->smc_brklen = 0; up->smc_brkec = 0; up->smc_brkcr = 0; up->smc_mrblr = 128; up->smc_maxidl = 8;
/* 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. */ ip->im_cpmux.cmx_smr = 0; #endif
/* The baud rate divisor needs to be coordinated with clk_8260(). */ ip->im_brgc1 = (((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN;
/* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
/* Initialize Tx/Rx parameters. */ #ifdef SCC_CONSOLE sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); #else cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG);
/* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; #endif }
void serial_putc(void *ignored, const char c) { volatile cbd_t *tbdf; volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; volatile immap_t *ip; extern bd_t *board_info;
ip = (immap_t *)IMAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase]; #else up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase]; #endif
/* Wait for last character to go. */ buf = (char *)tbdf->cbd_bufaddr; while (tbdf->cbd_sc & BD_SC_READY);
*buf = c; tbdf->cbd_datlen = 1; tbdf->cbd_sc |= BD_SC_READY; }
char serial_getc(void *ignored) { char c;
if (cons_hold_cnt <= 0) { cons_hold_cnt = serial_readbuf(cons_hold); sgptr = cons_hold; } c = *sgptr++; cons_hold_cnt--;
return(c); }
int serial_readbuf(u_char *cbuf) { volatile cbd_t *rbdf; volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; volatile immap_t *ip; int i, nc;
ip = (immap_t *)IMAP_ADDR;
#ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; #else up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; #endif
/* Wait for character to show up. */ buf = (char *)rbdf->cbd_bufaddr; while (rbdf->cbd_sc & BD_SC_EMPTY); nc = rbdf->cbd_datlen; for (i=0; i<nc; i++) *cbuf++ = *buf++; rbdf->cbd_sc |= BD_SC_EMPTY;
return(nc); }
int serial_tstc(void *ignored) { volatile cbd_t *rbdf; volatile smc_uart_t *up; volatile scc_uart_t *sup; volatile immap_t *ip;
ip = (immap_t *)IMAP_ADDR; #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; #else up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; #endif
return(!(rbdf->cbd_sc & BD_SC_EMPTY)); }
|