1/* 2 * BK Id: %F% %I% %G% %U% %#% 3 */ 4 5 6/* Minimal serial functions needed to send messages out the serial 7 * port on the MBX console. 8 * 9 * The MBX uxes SMC1 for the serial port. We reset the port and use 10 * only the first BD that EPPC-Bug set up as a character FIFO. 11 * 12 * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug 13 * use COM1 instead of SMC1 as the console port. This kinda sucks 14 * for the rest of the kernel, so here we force the use of SMC1 again. 15 */ 16#include <linux/config.h> 17#include <linux/types.h> 18#include <asm/uaccess.h> 19#include <asm/mpc8xx.h> 20#include <asm/commproc.h> 21 22#ifdef CONFIG_MBX 23#define MBX_CSR1 ((volatile u_char *)0xfa100000) 24#define CSR1_COMEN (u_char)0x02 25#endif 26 27#ifdef TQM_SMC2_CONSOLE 28#define PROFF_CONS PROFF_SMC2 29#define CPM_CR_CH_CONS CPM_CR_CH_SMC2 30#define SMC_INDEX 1 31static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport); 32#else 33#define PROFF_CONS PROFF_SMC1 34#define CPM_CR_CH_CONS CPM_CR_CH_SMC1 35#define SMC_INDEX 0 36#endif 37 38static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); 39 40unsigned long 41serial_init(int ignored, bd_t *bd) 42{ 43 volatile smc_t *sp; 44 volatile smc_uart_t *up; 45 volatile cbd_t *tbdf, *rbdf; 46 volatile cpm8xx_t *cp; 47 uint dpaddr, memaddr; 48#ifndef CONFIG_MBX 49 uint ui; 50#endif 51 52 cp = cpmp; 53 sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); 54 up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; 55 56 /* Disable transmitter/receiver. 57 */ 58 sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 59 60#ifdef CONFIG_FADS 61 /* Enable SMC1/2 transceivers. 62 */ 63 *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2); 64#endif 65 66#ifndef CONFIG_MBX 67 { 68 /* Initialize SMCx and use it for the console port. 69 */ 70 71 /* Enable SDMA. 72 */ 73 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; 74 75#ifdef TQM_SMC2_CONSOLE 76 /* Use Port A for SMC2 instead of other functions. 77 */ 78 iopp->iop_papar |= 0x00c0; 79 iopp->iop_padir &= ~0x00c0; 80 iopp->iop_paodr &= ~0x00c0; 81#else 82 /* Use Port B for SMCs instead of other functions. 83 */ 84 cp->cp_pbpar |= 0x00000cc0; 85 cp->cp_pbdir &= ~0x00000cc0; 86 cp->cp_pbodr &= ~0x00000cc0; 87#endif 88 89 /* Allocate space for two buffer descriptors in the DP ram. 90 * For now, this address seems OK, but it may have to 91 * change with newer versions of the firmware. 92 */ 93 dpaddr = 0x0800; 94 95 /* Grab a few bytes from the top of memory for SMC FIFOs. 96 */ 97 memaddr = (bd->bi_memsize - 32) & ~15; 98 99 /* Set the physical address of the host memory buffers in 100 * the buffer descriptors. 101 */ 102 rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; 103 rbdf->cbd_bufaddr = memaddr; 104 rbdf->cbd_sc = 0; 105 tbdf = rbdf + 1; 106 tbdf->cbd_bufaddr = memaddr+4; 107 tbdf->cbd_sc = 0; 108 109 /* Set up the uart parameters in the parameter ram. 110 */ 111 up->smc_rbase = dpaddr; 112 up->smc_tbase = dpaddr+sizeof(cbd_t); 113 up->smc_rfcr = SMC_EB; 114 up->smc_tfcr = SMC_EB; 115 116 /* Set UART mode, 8 bit, no parity, one stop. 117 * Enable receive and transmit. 118 */ 119 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; 120 121 /* Mask all interrupts and remove anything pending. 122 */ 123 sp->smc_smcm = 0; 124 sp->smc_smce = 0xff; 125 126 /* Set up the baud rate generator. 127 * See 8xx_io/commproc.c for details. 128 * This wires BRG1 to SMC1 and BRG2 to SMC2; 129 */ 130 cp->cp_simode = 0x10000000; 131 ui = bd->bi_intfreq / 16 / bd->bi_baudrate; 132#ifdef TQM_SMC2_CONSOLE 133 cp->cp_brgc2 = 134#else 135 cp->cp_brgc1 = 136#endif 137 ((ui - 1) < 4096) 138 ? (((ui - 1) << 1) | CPM_BRG_EN) 139 : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); 140 141#else /* CONFIG_MBX */ 142 if (*MBX_CSR1 & CSR1_COMEN) { 143 /* COM1 is enabled. Initialize SMC1 and use it for 144 * the console port. 145 */ 146 147 /* Enable SDMA. 148 */ 149 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; 150 151 /* Use Port B for SMCs instead of other functions. 152 */ 153 cp->cp_pbpar |= 0x00000cc0; 154 cp->cp_pbdir &= ~0x00000cc0; 155 cp->cp_pbodr &= ~0x00000cc0; 156 157 /* Allocate space for two buffer descriptors in the DP ram. 158 * For now, this address seems OK, but it may have to 159 * change with newer versions of the firmware. 160 */ 161 dpaddr = 0x0800; 162 163 /* Grab a few bytes from the top of memory. EPPC-Bug isn't 164 * running any more, so we can do this. 165 */ 166 memaddr = (bd->bi_memsize - 32) & ~15; 167 168 /* Set the physical address of the host memory buffers in 169 * the buffer descriptors. 170 */ 171 rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; 172 rbdf->cbd_bufaddr = memaddr; 173 rbdf->cbd_sc = 0; 174 tbdf = rbdf + 1; 175 tbdf->cbd_bufaddr = memaddr+4; 176 tbdf->cbd_sc = 0; 177 178 /* Set up the uart parameters in the parameter ram. 179 */ 180 up->smc_rbase = dpaddr; 181 up->smc_tbase = dpaddr+sizeof(cbd_t); 182 up->smc_rfcr = SMC_EB; 183 up->smc_tfcr = SMC_EB; 184 185 /* Set UART mode, 8 bit, no parity, one stop. 186 * Enable receive and transmit. 187 */ 188 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; 189 190 /* Mask all interrupts and remove anything pending. 191 */ 192 sp->smc_smcm = 0; 193 sp->smc_smce = 0xff; 194 195 /* Set up the baud rate generator. 196 * See 8xx_io/commproc.c for details. 197 */ 198 cp->cp_simode = 0x10000000; 199 cp->cp_brgc1 = 200 (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN; 201 202 /* Enable SMC1 for console output. 203 */ 204 *MBX_CSR1 &= ~CSR1_COMEN; 205 } 206 else { 207#endif /* ndef CONFIG_MBX */ 208 /* SMCx is used as console port. 209 */ 210 tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; 211 rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; 212 213 /* Issue a stop transmit, and wait for it. 214 */ 215 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, 216 CPM_CR_STOP_TX) | CPM_CR_FLG; 217 while (cp->cp_cpcr & CPM_CR_FLG); 218 } 219 220 /* Make the first buffer the only buffer. 221 */ 222 tbdf->cbd_sc |= BD_SC_WRAP; 223 rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; 224 225 /* Single character receive. 226 */ 227 up->smc_mrblr = 1; 228 up->smc_maxidl = 0; 229 230 /* Initialize Tx/Rx parameters. 231 */ 232 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; 233 while (cp->cp_cpcr & CPM_CR_FLG); 234 235 /* Enable transmitter/receiver. 236 */ 237 sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; 238 239 /* This is ignored. 240 */ 241 return 0; 242} 243 244void 245serial_putc(void *ignored, const char c) 246{ 247 volatile cbd_t *tbdf; 248 volatile char *buf; 249 volatile smc_uart_t *up; 250 251 up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; 252 tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; 253 254 /* Wait for last character to go. 255 */ 256 buf = (char *)tbdf->cbd_bufaddr; 257 while (tbdf->cbd_sc & BD_SC_READY); 258 259 *buf = c; 260 tbdf->cbd_datlen = 1; 261 tbdf->cbd_sc |= BD_SC_READY; 262} 263 264char 265serial_getc(void *ignored) 266{ 267 volatile cbd_t *rbdf; 268 volatile char *buf; 269 volatile smc_uart_t *up; 270 char c; 271 272 up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; 273 rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; 274 275 /* Wait for character to show up. 276 */ 277 buf = (char *)rbdf->cbd_bufaddr; 278 while (rbdf->cbd_sc & BD_SC_EMPTY); 279 c = *buf; 280 rbdf->cbd_sc |= BD_SC_EMPTY; 281 282 return(c); 283} 284 285int 286serial_tstc(void *ignored) 287{ 288 volatile cbd_t *rbdf; 289 volatile smc_uart_t *up; 290 291 up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; 292 rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; 293 294 return(!(rbdf->cbd_sc & BD_SC_EMPTY)); 295} 296 297void 298serial_close(unsigned long com_port) 299{ 300} 301