serial: Make ucc_uart work in HW UART mode

In HW UART mode the TxBD[READY] is not cleared by H/W (RISC engine) when
the user send characters to Tx buffer of QE UART.  So, these characters
stay on the QE forever, never go to UART line.

Signed-off-by: Dave Liu <daveliu@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
Dave Liu 2009-06-08 22:24:36 +08:00 committed by Kumar Gala
parent f1f8b4948d
commit b45cc9eff7

View File

@ -681,22 +681,27 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
out_be16(&uccup->rccm, 0xc0ff); out_be16(&uccup->rccm, 0xc0ff);
/* Configure the GUMR registers for UART */ /* Configure the GUMR registers for UART */
if (soft_uart) if (soft_uart) {
/* Soft-UART requires a 1X multiplier for TX */ /* Soft-UART requires a 1X multiplier for TX */
clrsetbits_be32(&uccp->gumr_l, clrsetbits_be32(&uccp->gumr_l,
UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
UCC_SLOW_GUMR_L_RDCR_MASK, UCC_SLOW_GUMR_L_RDCR_MASK,
UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 | UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 |
UCC_SLOW_GUMR_L_RDCR_16); UCC_SLOW_GUMR_L_RDCR_16);
else
clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW,
UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX);
} else {
clrsetbits_be32(&uccp->gumr_l, clrsetbits_be32(&uccp->gumr_l,
UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
UCC_SLOW_GUMR_L_RDCR_MASK, UCC_SLOW_GUMR_L_RDCR_MASK,
UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 | UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 |
UCC_SLOW_GUMR_L_RDCR_16); UCC_SLOW_GUMR_L_RDCR_16);
clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW, clrsetbits_be32(&uccp->gumr_h,
UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX); UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX,
UCC_SLOW_GUMR_H_RFW);
}
#ifdef LOOPBACK #ifdef LOOPBACK
clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
@ -706,7 +711,7 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
UCC_SLOW_GUMR_H_CDS); UCC_SLOW_GUMR_H_CDS);
#endif #endif
/* Enable rx interrupts and clear all pending events. */ /* Disable rx interrupts and clear all pending events. */
out_be16(&uccp->uccm, 0); out_be16(&uccp->uccm, 0);
out_be16(&uccp->ucce, 0xffff); out_be16(&uccp->ucce, 0xffff);
out_be16(&uccp->udsr, 0x7e7e); out_be16(&uccp->udsr, 0x7e7e);
@ -765,6 +770,10 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num); cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num);
qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock, qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
QE_CR_PROTOCOL_UNSPECIFIED, 0); QE_CR_PROTOCOL_UNSPECIFIED, 0);
} else {
cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num);
qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
QE_CR_PROTOCOL_UART, 0);
} }
} }