patch-2.4.23 linux-2.4.23/arch/ppc/8xx_io/uart.c
Next file: linux-2.4.23/arch/ppc/Makefile
Previous file: linux-2.4.23/arch/ppc/8xx_io/fec.c
Back to the patch index
Back to the overall index
- Lines: 692
- Date:
2003-11-28 10:26:19.000000000 -0800
- Orig file:
linux-2.4.22/arch/ppc/8xx_io/uart.c
- Orig date:
2003-08-25 04:44:40.000000000 -0700
diff -urN linux-2.4.22/arch/ppc/8xx_io/uart.c linux-2.4.23/arch/ppc/8xx_io/uart.c
@@ -81,7 +81,11 @@
#define TX_WAKEUP ASYNC_SHARE_IRQ
static char *serial_name = "CPM UART driver";
-static char *serial_version = "0.03";
+static char *serial_version = "0.04";
+
+/* TX buffer length used by my_console_write.
+ Assume minumun length until it gets set by this driver */
+static int console_tx_buf_len = 1;
static DECLARE_TASK_QUEUE(tq_serial);
@@ -126,10 +130,27 @@
* type of SMC or SCC.
* The SMCs do not support any modem control signals.
*/
-#define smc_scc_num hub6
-#define NUM_IS_SCC ((int)0x00010000)
-#define PORT_NUM(P) ((P) & 0x0000ffff)
-#define PORT_IS_SCC(P) ((P) & NUM_IS_SCC)
+#define smc_scc_num hub6
+#define NUM_IS_SCC ((int)0x000100000)
+#define NUM_BRG ((int)0x0000FF00)
+#define NUM_BRG_SHIFT 8
+#define NUM ((int)0x000000FF)
+#define NUM_SHIFT 0
+#define PORT_NUM(P) ((P) & NUM)
+#define PORT_NUM_SET(N) (((N)-1) << NUM_SHIFT)
+#define PORT_IS_SCC(P) ((P) & NUM_IS_SCC)
+#define PORT_BRG(P) (((P) & NUM_BRG) >> NUM_BRG_SHIFT)
+#define PORT_BRG_SET(P,B) (P) = (((P) & ~NUM_BRG) | ((B) << NUM_BRG_SHIFT))
+
+/* Short names for the ports
+*/
+#define QUICC_CPM_SMC1 (PORT_NUM_SET(1))
+#define QUICC_CPM_SMC2 (PORT_NUM_SET(2))
+#define QUICC_CPM_SCC1 (PORT_NUM_SET(1)|NUM_IS_SCC)
+#define QUICC_CPM_SCC2 (PORT_NUM_SET(2)|NUM_IS_SCC)
+#define QUICC_CPM_SCC3 (PORT_NUM_SET(3)|NUM_IS_SCC)
+#define QUICC_CPM_SCC4 (PORT_NUM_SET(4)|NUM_IS_SCC)
+#define QUICC_MAX_BRG 3 /* BRG1..BRG4 */
/* The serial port to use for KGDB. */
#ifdef CONFIG_KGDB_TTYS1
@@ -151,22 +172,24 @@
*/
static struct serial_state rs_table[] = {
/* UART CLK PORT IRQ FLAGS NUM */
-#ifndef CONFIG_SCC3_ENET /* SMC1 not usable with Ethernet on SCC3 */
- { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */
+#ifdef CONFIG_8xx_SMC1
+ { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, QUICC_CPM_SMC1 }, /* SMC1 ttySx */
+#endif
+#ifdef CONFIG_8xx_SMC2
+ { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, QUICC_CPM_SMC2 }, /* SMC2 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC1
+ { 0, 0, PROFF_SCC1, CPMVEC_SCC1, 0, QUICC_CPM_SCC1 }, /* SCC1 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC2
+ { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, QUICC_CPM_SCC2 }, /* SCC2 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC3
+ { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, QUICC_CPM_SCC3 }, /* SCC3 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC4
+ { 0, 0, PROFF_SCC4, CPMVEC_SCC4, 0, QUICC_CPM_SCC4 }, /* SCC4 ttySx */
#endif
-#if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx)
-# ifdef CONFIG_SMC2_UART
- { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */
-# endif
-# ifdef CONFIG_USE_SCC_IO
- { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */
- { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */
-# endif
- #else /* CONFIG_USB_xxx */
-# ifdef CONFIG_USE_SCC_IO
- { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */
-# endif
-#endif /* CONFIG_USB_xxx */
};
#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state))
@@ -177,6 +200,7 @@
/* The number of buffer descriptors and their sizes.
*/
+#define EARLY_BUF_SIZE 4
#define RX_NUM_FIFO 4
#define RX_BUF_SIZE 32
#define TX_NUM_FIFO 4
@@ -218,6 +242,12 @@
cbd_t *rx_cur;
cbd_t *tx_bd_base;
cbd_t *tx_cur;
+
+ /* Virtual addresses for the FIFOs because we can't __va() a
+ * physical address anymore.
+ */
+ unsigned char *rx_va_base;
+ unsigned char *tx_va_base;
} ser_info_t;
static struct console sercons = {
@@ -394,13 +424,13 @@
/* Get the number of characters and the buffer pointer.
*/
i = bdp->cbd_datlen;
- cp = (unsigned char *)__va(bdp->cbd_bufaddr);
+ cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE);
status = bdp->cbd_sc;
#ifdef CONFIG_KGDB
- if (info->state->smc_scc_num == KGDB_SER_IDX) {
- if (*cp == 0x03 || *cp == '$')
- breakpoint();
+ if (info->state->smc_scc_num == KGDB_SER_IDX &&
+ (*cp == 0x03 || *cp == '$')) {
+ breakpoint();
return;
}
#endif
@@ -420,7 +450,7 @@
icount->rx++;
#ifdef SERIAL_DEBUG_INTR
- printk("DR%02x:%02x...", ch, status);
+ printk("DR%02x:%02x...", ch, status);
#endif
*tty->flip.flag_buf_ptr = 0;
if (status & (BD_SC_BR | BD_SC_FR |
@@ -1033,7 +1063,7 @@
smcp->smc_smcmr = new_mode;
}
- m8xx_cpm_setbrg((state - rs_table), baud_rate);
+ m8xx_cpm_setbrg(PORT_BRG(state->smc_scc_num), baud_rate);
restore_flags(flags);
}
@@ -1042,6 +1072,8 @@
{
ser_info_t *info = (ser_info_t *)tty->driver_data;
volatile cbd_t *bdp;
+ unsigned char *cp;
+ unsigned long flags;
if (serial_paranoia_check(info, tty->device, "rs_put_char"))
return;
@@ -1049,21 +1081,22 @@
if (!tty)
return;
+ local_irq_save(flags);
bdp = info->tx_cur;
- while (bdp->cbd_sc & BD_SC_READY);
-
- *((char *)__va(bdp->cbd_bufaddr)) = ch;
- bdp->cbd_datlen = 1;
- bdp->cbd_sc |= BD_SC_READY;
-
/* Get next BD.
*/
if (bdp->cbd_sc & BD_SC_WRAP)
- bdp = info->tx_bd_base;
+ info->tx_cur = info->tx_bd_base;
else
- bdp++;
+ info->tx_cur = (cbd_t *)bdp + 1;
+ local_irq_restore(flags);
- info->tx_cur = (cbd_t *)bdp;
+ while (bdp->cbd_sc & BD_SC_READY);
+
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
+ *cp = ch;
+ bdp->cbd_datlen = 1;
+ bdp->cbd_sc |= BD_SC_READY;
}
@@ -1073,6 +1106,8 @@
int c, ret = 0;
ser_info_t *info = (ser_info_t *)tty->driver_data;
volatile cbd_t *bdp;
+ unsigned char *cp;
+ unsigned long flags;
#ifdef CONFIG_KGDB_CONSOLE
/* Try to let stub handle output. Returns true if it did. */
@@ -1086,43 +1121,50 @@
if (!tty)
return 0;
- bdp = info->tx_cur;
-
while (1) {
c = MIN(count, TX_BUF_SIZE);
if (c <= 0)
break;
+ local_irq_save(flags);
+ bdp = info->tx_cur;
if (bdp->cbd_sc & BD_SC_READY) {
info->flags |= TX_WAKEUP;
+ local_irq_restore(flags);
break;
}
+ /* Get next BD.
+ */
+ if (bdp->cbd_sc & BD_SC_WRAP)
+ info->tx_cur = info->tx_bd_base;
+ else
+ info->tx_cur = (cbd_t *)bdp + 1;
+ local_irq_restore(flags);
- if (from_user) {
- if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
- } else {
- memcpy(__va(bdp->cbd_bufaddr), buf, c);
- }
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) *
+ TX_BUF_SIZE);
+ if (from_user)
+ c -= copy_from_user((void *)cp, buf, c);
+ else
+ memcpy((void *)cp, buf, c);
- bdp->cbd_datlen = c;
- bdp->cbd_sc |= BD_SC_READY;
+ if (c) {
+ bdp->cbd_datlen = c;
+ bdp->cbd_sc |= BD_SC_READY;
+ } else {
+ /* Need to TX at least 1 char to keep CPM sane */
+ bdp->cbd_datlen = 1;
+ *cp = 0;
+ bdp->cbd_sc |= BD_SC_READY;
+ if (!ret)
+ ret = -EFAULT;
+ break;
+ }
buf += c;
count -= c;
ret += c;
-
- /* Get next BD.
- */
- if (bdp->cbd_sc & BD_SC_WRAP)
- bdp = info->tx_bd_base;
- else
- bdp++;
- info->tx_cur = (cbd_t *)bdp;
}
return ret;
}
@@ -1181,27 +1223,29 @@
static void rs_8xx_send_xchar(struct tty_struct *tty, char ch)
{
volatile cbd_t *bdp;
+ unsigned char *cp;
+ unsigned long flags;
ser_info_t *info = (ser_info_t *)tty->driver_data;
if (serial_paranoia_check(info, tty->device, "rs_send_char"))
return;
+ local_irq_save(flags);
bdp = info->tx_cur;
- while (bdp->cbd_sc & BD_SC_READY);
-
- *((char *)__va(bdp->cbd_bufaddr)) = ch;
- bdp->cbd_datlen = 1;
- bdp->cbd_sc |= BD_SC_READY;
-
/* Get next BD.
*/
if (bdp->cbd_sc & BD_SC_WRAP)
- bdp = info->tx_bd_base;
+ info->tx_cur = info->tx_bd_base;
else
- bdp++;
+ info->tx_cur = (cbd_t *)bdp + 1;
+ local_irq_restore(flags);
+ while (bdp->cbd_sc & BD_SC_READY);
- info->tx_cur = (cbd_t *)bdp;
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
+ *cp = ch;
+ bdp->cbd_datlen = 1;
+ bdp->cbd_sc |= BD_SC_READY;
}
/*
@@ -1772,7 +1816,7 @@
static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout)
{
ser_info_t *info = (ser_info_t *)tty->driver_data;
- unsigned long orig_jiffies, char_time;
+ unsigned long orig_jiffies, char_time, tst_res;
/*int lsr;*/
volatile cbd_t *bdp;
@@ -1807,6 +1851,7 @@
* are empty.
*/
do {
+ unsigned long flags;
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
#endif
@@ -1824,12 +1869,15 @@
* is the buffer is available. There are still characters
* in the CPM FIFO.
*/
+ local_irq_save(flags);
bdp = info->tx_cur;
if (bdp == info->tx_bd_base)
bdp += (TX_NUM_FIFO-1);
else
bdp--;
- } while (bdp->cbd_sc & BD_SC_READY);
+ tst_res = !!(bdp->cbd_sc & BD_SC_READY);
+ local_irq_restore(flags);
+ } while (tst_res);
current->state = TASK_RUNNING;
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
@@ -2217,6 +2265,11 @@
#ifdef CONFIG_SERIAL_CONSOLE
+/* I need this just so I can store the virtual addresses and have
+ * common functions for the early console printing.
+ */
+static ser_info_t consinfo;
+
/*
* Print a string to the serial port trying not to disturb any possible
* real use of the port...
@@ -2226,10 +2279,11 @@
{
struct serial_state *ser;
ser_info_t *info;
- unsigned i;
+ unsigned i, c, cr_missing, max_tx_size;
volatile cbd_t *bdp, *bdbase;
volatile smc_uart_t *up;
volatile u_char *cp;
+ unsigned long flags;
ser = rs_table + idx;
@@ -2238,82 +2292,72 @@
* we simply use the single buffer allocated.
*/
if ((info = (ser_info_t *)ser->info) != NULL) {
- bdp = info->tx_cur;
bdbase = info->tx_bd_base;
- }
- else {
- /* Pointer to UART in parameter ram.
- */
+ } else {
+ /* Pointer to UART in parameter ram. */
up = (smc_uart_t *)&cpmp->cp_dparam[ser->port];
- /* Get the address of the host memory buffer.
- */
- bdp = bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
- }
+ /* Get the address of the host memory buffer.*/
+ info = &consinfo;
+ info->tx_bd_base = (cbd_t *)bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+ info->tx_cur = (cbd_t *)bdbase;
+ }
+ max_tx_size = console_tx_buf_len;
+ cr_missing = 0;
+ while (1){
+ c = MIN(max_tx_size, count);
+ if (c <= 0)
+ break;
- /*
- * We need to gracefully shut down the transmitter, disable
- * interrupts, then send our bytes out.
- */
+ local_irq_save(flags);
+ bdp = info->tx_cur;
+ bdbase = info->tx_bd_base;
+ if (bdp->cbd_sc & BD_SC_WRAP)
+ info->tx_cur = (cbd_t *)bdbase;
+ else
+ info->tx_cur = (cbd_t *)(bdp+1);
+ local_irq_restore(flags);
- /*
- * Now, do each character. This is not as bad as it looks
- * since this is a holding FIFO and not a transmitting FIFO.
- * We could add the complexity of filling the entire transmit
- * buffer, but we would just wait longer between accesses......
- */
- for (i = 0; i < count; i++, s++) {
/* Wait for transmitter fifo to empty.
* Ready indicates output is ready, and xmt is doing
* that, not that it is ready for us to send.
*/
while (bdp->cbd_sc & BD_SC_READY);
- /* Send the character out.
+ /* Send the characters out.
* If the buffer address is in the CPM DPRAM, don't
* convert it.
*/
if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
cp = (u_char *)(bdp->cbd_bufaddr);
else
- cp = __va(bdp->cbd_bufaddr);
- *cp = *s;
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
- bdp->cbd_datlen = 1;
+ i=1; /* Keeps track of consumed TX buffer space */
+ if (cr_missing) {
+ /* Previus loop didn't have room for the CR, insert it first in this */
+ *cp++ = '\r';
+ i++;
+ }
+ cr_missing = 0;
+ for (; i <= c; i++) {
+ if ((*cp++ = *s++) != '\n')
+ continue; /* Copy bytes until a NewLine is found */
+ /* NewLine found, see if there is space in the TX buffer to add a CR */
+ if (i < max_tx_size) {
+ *cp++ = '\r'; /* yes, there is space to add a CR */
+ i++;
+ } else
+ cr_missing = 1; /* No space in the TX buffer,
+ rember it so it can be inserted in the next loop */
+ }
+ count -= (c-cr_missing);
+ bdp->cbd_datlen = i-1;
bdp->cbd_sc |= BD_SC_READY;
- if (bdp->cbd_sc & BD_SC_WRAP)
- bdp = bdbase;
- else
- bdp++;
-
- /* if a LF, also do CR... */
- if (*s == 10) {
- while (bdp->cbd_sc & BD_SC_READY);
- cp = __va(bdp->cbd_bufaddr);
- *cp = 13;
- bdp->cbd_datlen = 1;
- bdp->cbd_sc |= BD_SC_READY;
-
- if (bdp->cbd_sc & BD_SC_WRAP) {
- bdp = bdbase;
- }
- else {
- bdp++;
- }
- }
}
-
- /*
- * Finally, Wait for transmitter & holding register to empty
- * and restore the IER
- */
- while (bdp->cbd_sc & BD_SC_READY);
-
- if (info)
- info->tx_cur = (cbd_t *)bdp;
+ /* while (bdp->cbd_sc & BD_SC_READY); is this really needed? */
}
-
static void serial_console_write(struct console *c, const char *s,
unsigned count)
{
@@ -2358,10 +2402,13 @@
* If the port has been initialized for general use, we must
* use information from the port structure.
*/
- if ((info = (ser_info_t *)ser->info))
+ if ((info = (ser_info_t *)ser->info)) {
bdp = info->rx_cur;
- else
+ }
+ else {
bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+ info = &consinfo;
+ }
/*
* We need to gracefully shut down the receiver, disable
@@ -2383,7 +2430,7 @@
if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
cp = (u_char *)(bdp->cbd_bufaddr);
else
- cp = __va(bdp->cbd_bufaddr);
+ cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE);
if (obuf) {
i = c = bdp->cbd_datlen;
@@ -2522,6 +2569,43 @@
/*
* The serial driver boot-time initialization code!
*/
+
+int __init rs_8xx_alloc_brg(int port)
+{
+ static int brg = 0;
+ volatile cpm8xx_t *cp = cpmp;
+ int res = brg;
+
+ /* "Wire" the BRG to the specified port
+ */
+ switch (port) {
+ case QUICC_CPM_SMC1:
+ cp->cp_simode = (cp->cp_simode & ~(0x07<<12)) | (brg<<12);
+ break;
+ case QUICC_CPM_SMC2:
+ cp->cp_simode = (cp->cp_simode & ~(0x07<<28)) | (brg<<28);
+ break;
+ case QUICC_CPM_SCC1:
+ cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<0)) | (((brg<<3)|(brg<<0))<<0);
+ break;
+ case QUICC_CPM_SCC2:
+ cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<8)) | (((brg<<3)|(brg<<0))<<8);
+ break;
+ case QUICC_CPM_SCC3:
+ cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<16)) | (((brg<<3)|(brg<<0))<<16);
+ break;
+ case QUICC_CPM_SCC4:
+ cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<24)) | (((brg<<3)|(brg<<0))<<24);
+ break;
+ }
+ /* Consume this BRG - Note: the last BRG will be reused if this
+ */
+ /* function is called too many times!
+ */
+ if (brg < QUICC_MAX_BRG) brg++;
+ return res;
+}
+
int __init rs_8xx_init(void)
{
struct serial_state * state;
@@ -2668,9 +2752,12 @@
state->icount.rx = state->icount.tx = 0;
state->icount.frame = state->icount.parity = 0;
state->icount.overrun = state->icount.brk = 0;
- printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n",
+ PORT_BRG_SET(state->smc_scc_num, rs_8xx_alloc_brg(state->smc_scc_num));
+ printk(KERN_INFO "ttyS%d at 0x%04x is on %s%d using BRG%d\n",
i, (unsigned int)(state->port),
- PORT_IS_SCC(state->smc_scc_num) ? "SCC" : "SMC");
+ PORT_IS_SCC(state->smc_scc_num) ? "SCC" : "SMC",
+ PORT_NUM(state->smc_scc_num)+1,
+ PORT_BRG(state->smc_scc_num)+1);
#ifdef CONFIG_SERIAL_CONSOLE
/* If we just printed the message on the console port, and
* we are about to initialize it for general use, we have
@@ -2704,6 +2791,7 @@
/* Allocate space for FIFOs in the host memory.
*/
mem_addr = m8xx_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE);
+ info->rx_va_base = (unsigned char *)mem_addr;
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -2713,12 +2801,12 @@
info->rx_cur = info->rx_bd_base = (cbd_t *)bdp;
for (j=0; j<(RX_NUM_FIFO-1); j++) {
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
mem_addr += RX_BUF_SIZE;
bdp++;
}
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
idx = PORT_NUM(info->state->smc_scc_num);
@@ -2738,6 +2826,7 @@
/* Allocate space for FIFOs in the host memory.
*/
mem_addr = m8xx_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE);
+ info->tx_va_base = (unsigned char *)mem_addr;
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -2747,12 +2836,12 @@
info->tx_cur = info->tx_bd_base = (cbd_t *)bdp;
for (j=0; j<(TX_NUM_FIFO-1); j++) {
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = BD_SC_INTRPT;
mem_addr += TX_BUF_SIZE;
bdp++;
}
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
if (PORT_IS_SCC(info->state->smc_scc_num)) {
@@ -2846,12 +2935,14 @@
}
#endif /* CONFIG_ALTSMC2 */
+#if 0
/* Connect the baud rate generator to the
* SMC based upon index in rs_table. Also
* make sure it is connected to NMSI.
*/
cp->cp_simode &= ~(0xffff << (idx * 16));
cp->cp_simode |= (i << ((idx * 16) + 12));
+#endif
up->smc_tbase = dp_addr;
@@ -2903,11 +2994,11 @@
/* Set up the baud rate generator.
*/
- m8xx_cpm_setbrg(i, baud_table[baud_idx]);
+ m8xx_cpm_setbrg(PORT_BRG(state->smc_scc_num), baud_table[baud_idx]);
}
}
-
+ console_tx_buf_len = TX_BUF_SIZE;
return 0;
}
@@ -2959,20 +3050,28 @@
* from dual port ram, and a character buffer area from host mem.
*/
+ /* Allocate space for two FIFOs. We can't allocate from host
+ * memory yet because vm allocator isn't initialized
+ * during this early console init.
+ */
+ dp_addr = m8xx_cpm_dpalloc(2*EARLY_BUF_SIZE);
+ mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]);
+
/* Allocate space for two buffer descriptors in the DP ram.
*/
dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2);
- /* Allocate space for two 2 byte FIFOs in the host memory.
- */
- mem_addr = m8xx_cpm_hostalloc(8);
-
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
*/
bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
- bdp->cbd_bufaddr = __pa(mem_addr);
- (bdp+1)->cbd_bufaddr = __pa(mem_addr+4);
+ bdp->cbd_bufaddr = iopa(mem_addr);
+ (bdp+1)->cbd_bufaddr = iopa(mem_addr+4);
+
+ consinfo.rx_va_base = (unsigned char *) mem_addr;
+ consinfo.rx_bd_base = (cbd_t *) bdp;
+ consinfo.tx_va_base = (unsigned char *) (mem_addr + EARLY_BUF_SIZE);
+ consinfo.tx_bd_base = (cbd_t *) (bdp+1);
/* For the receive, set empty and wrap.
* For transmit, set wrap.
@@ -3073,7 +3172,7 @@
/* Set up the baud rate generator.
*/
m8xx_cpm_setbrg((ser - rs_table), bd->bi_baudrate);
-
+ console_tx_buf_len = EARLY_BUF_SIZE;
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)