diff options
author | Timur Tabi <timur@freescale.com> | 2007-10-03 20:34:59 +0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2007-10-08 17:38:15 +0400 |
commit | 6b0b594bb81f86dbc7b0829ee5102abaab242913 (patch) | |
tree | 707463987ab05d04596763afa9db1c63cbde4c4a /arch/powerpc/sysdev/qe_lib/qe.c | |
parent | 6039680705906f270411435c05c869ac4f59ef10 (diff) | |
download | linux-6b0b594bb81f86dbc7b0829ee5102abaab242913.tar.xz |
[POWERPC] qe: miscellaneous code improvements and fixes to the QE library
This patch makes numerous miscellaneous code improvements to the QE library.
1. Remove struct ucc_common and merge ucc_init_guemr() into ucc_set_type()
(every caller of ucc_init_guemr() also calls ucc_set_type()). Modify all
callers of ucc_set_type() accordingly.
2. Remove the unused enum ucc_pram_initial_offset.
3. Refactor qe_setbrg(), also implement work-around for errata QE_General4.
4. Several printk() calls were missing the terminating \n.
5. Add __iomem where needed, and change u16 to __be16 and u32 to __be32 where
appropriate.
6. In ucc_slow_init() the RBASE and TBASE registers in the PRAM were programmed
with the wrong value.
7. Add the protocol type to struct us_info and updated ucc_slow_init() to
use it, instead of always programming QE_CR_PROTOCOL_UNSPECIFIED.
8. Rename ucc_slow_restart_x() to ucc_slow_restart_tx()
9. Add several macros in qe.h (mostly for slow UCC support, but also to
standardize some naming convention) and remove several unused macros.
10. Update ucc_geth.c to use the new macros.
11. Add ucc_slow_info.protocol to specify which QE_CR_PROTOCOL_xxx protcol
to use when initializing the UCC in ucc_slow_init().
12. Rename ucc_slow_pram.rfcr to rbmr and ucc_slow_pram.tfcr to tbmr, since
these are the real names of the registers.
13. Use the setbits, clrbits, and clrsetbits where appropriate.
14. Refactor ucc_set_qe_mux_rxtx().
15. Remove all instances of 'volatile'.
16. Simplify get_cmxucr_reg();
17. Replace qe_mux.cmxucrX with qe_mux.cmxucr[].
18. Updated struct ucc_geth because struct ucc_fast is not padded any more.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev/qe_lib/qe.c')
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 90f87408b5d5..3d57d3835b04 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -141,7 +141,7 @@ EXPORT_SYMBOL(qe_issue_cmd); * 16 BRGs, which can be connected to the QE channels or output * as clocks. The BRGs are in two different block of internal * memory mapped space. - * The baud rate clock is the system clock divided by something. + * The BRG clock is the QE clock divided by 2. * It was set up long ago during the initial boot phase and is * is given to us. * Baud rate clocks are zero-based in the driver code (as that maps @@ -165,28 +165,38 @@ unsigned int get_brg_clk(void) return brg_clk; } -/* This function is used by UARTS, or anything else that uses a 16x - * oversampled clock. +/* Program the BRG to the given sampling rate and multiplier + * + * @brg: the BRG, 1-16 + * @rate: the desired sampling rate + * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or + * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01, + * then 'multiplier' should be 8. + * + * Also note that the value programmed into the BRGC register must be even. */ -void qe_setbrg(u32 brg, u32 rate) +void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier) { - volatile u32 *bp; u32 divisor, tempval; - int div16 = 0; + u32 div16 = 0; - bp = &qe_immr->brg.brgc[brg]; + divisor = get_brg_clk() / (rate * multiplier); - divisor = (get_brg_clk() / rate); if (divisor > QE_BRGC_DIVISOR_MAX + 1) { - div16 = 1; + div16 = QE_BRGC_DIV16; divisor /= 16; } - tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE; - if (div16) - tempval |= QE_BRGC_DIV16; + /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says + that the BRG divisor must be even if you're not using divide-by-16 + mode. */ + if (!div16 && (divisor & 1)) + divisor++; + + tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | + QE_BRGC_ENABLE | div16; - out_be32(bp, tempval); + out_be32(&qe_immr->brg.brgc[brg - 1], tempval); } /* Initialize SNUMs (thread serial numbers) according to |