qe: miscellaneous code improvements and fixes to the QE library
Subsystems (2)
PATCH v3 1/1 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[].
---
Added changes 13 - 17.
arch/powerpc/sysdev/qe_lib/qe.c | 36 +++-- arch/powerpc/sysdev/qe_lib/qe_ic.c | 2 - arch/powerpc/sysdev/qe_lib/qe_io.c | 35 ++--- arch/powerpc/sysdev/qe_lib/ucc.c | 270 ++++++++++++++------------------- arch/powerpc/sysdev/qe_lib/ucc_fast.c | 127 ++++++++-------- arch/powerpc/sysdev/qe_lib/ucc_slow.c | 48 +++--- drivers/net/ucc_geth.c | 2 +- include/asm-powerpc/immap_qe.h | 30 ++--- include/asm-powerpc/qe.h | 243 ++++++++++++++++++++--------- include/asm-powerpc/ucc.h | 40 ++---- include/asm-powerpc/ucc_slow.h | 9 +- 11 files changed, 430 insertions(+), 412 deletions(-)
arch/powerpc/sysdev/qe_lib/qe.c +23 -13
@@ -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
arch/powerpc/sysdev/qe_lib/qe_ic.c +0 -2
@@ -405,8 +405,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags)set_irq_data (qe_ic->virq_high, qe_ic);set_irq_chained_handler (qe_ic->virq_high, qe_ic_cascade_high); } - -printk ("QEIC (%d IRQ sources) at %p\n" ,NR_QE_IC_INTS , qe_ic->regs); }void qe_ic_set_highest_priority (unsigned int virq,int high)
arch/powerpc/sysdev/qe_lib/qe_io.c +14 -21
@@ -195,29 +195,22 @@ EXPORT_SYMBOL(par_io_of_config);#ifdef DEBUG static void dump_par_io (void ) { -int i; +unsigned int i; -printk (KERN_INFO "PAR IO registars:\n" ); -printk (KERN_INFO "Base address: 0x%08x\n" , (u32 ) par_io); +printk (KERN_INFO "%s: par_io=%p\n" , __FUNCTION__, par_io);for (i =0 ; i < num_par_io_ports; i++) { -printk (KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n" , - i, (u32) & par_io[i].cpodr, -in_be32 (&par_io[i].cpodr)); -printk (KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n" , - i, (u32) & par_io[i].cpdata, -in_be32 (&par_io[i].cpdata)); -printk (KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n" , - i, (u32) & par_io[i].cpdir1, -in_be32 (&par_io[i].cpdir1)); -printk (KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n" , - i, (u32) & par_io[i].cpdir2, -in_be32 (&par_io[i].cpdir2)); -printk (KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n" , - i, (u32) & par_io[i].cppar1, -in_be32 (&par_io[i].cppar1)); -printk (KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n" , - i, (u32) & par_io[i].cppar2, -in_be32 (&par_io[i].cppar2)); +printk (KERN_INFO " cpodr[%u]=%08x\n" , i, +in_be32 (&par_io[i].cpodr)); +printk (KERN_INFO " cpdata[%u]=%08x\n" , i, +in_be32 (&par_io[i].cpdata)); +printk (KERN_INFO " cpdir1[%u]=%08x\n" , i, +in_be32 (&par_io[i].cpdir1)); +printk (KERN_INFO " cpdir2[%u]=%08x\n" , i, +in_be32 (&par_io[i].cpdir2)); +printk (KERN_INFO " cppar1[%u]=%08x\n" , i, +in_be32 (&par_io[i].cppar1)); +printk (KERN_INFO " cppar2[%u]=%08x\n" , i, +in_be32 (&par_io[i].cppar2)); } }
arch/powerpc/sysdev/qe_lib/ucc.c +115 -155
343 lines not on this page · raw message
arch/powerpc/sysdev/qe_lib/ucc_fast.c +61 -66
215 lines not on this page · raw message
arch/powerpc/sysdev/qe_lib/ucc_slow.c +23 -25
124 lines not on this page · raw message
drivers/net/ucc_geth.c +1 -1
@@ -2919,7 +2919,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) test =in_be16 (&ugeth->p_tx_glbl_pram->temoder);/* Function code register value to be used later */ - function_code =QE_BMR_BYTE_ORDER_BO_MOT |UCC_FAST_FUNCTION_CODE_GBL ; + function_code =UCC_BMR_BO_BE |UCC_BMR_GBL ;/* Required for QE */ /* function code register */
include/asm-powerpc/immap_qe.h +10 -20
@@ -96,10 +96,7 @@ struct qe_mux {__be32 cmxsi1cr_l;/* CMX SI1 clock route low register */ __be32 cmxsi1cr_h;/* CMX SI1 clock route high register */ __be32 cmxsi1syr;/* CMX SI1 SYNC route register */ -__be32 cmxucr1;/* CMX UCC1, UCC3 clock route register */ -__be32 cmxucr2;/* CMX UCC5, UCC7 clock route register */ -__be32 cmxucr3;/* CMX UCC2, UCC4 clock route register */ -__be32 cmxucr4;/* CMX UCC6, UCC8 clock route register */ +__be32 cmxucr[4 ];/* CMX UCCx clock route registers */ __be32 cmxupcr;/* CMX UPC clock route register */ u8 res0[0x1C ]; } __attribute__ ((packed));
@@ -260,7 +257,6 @@ struct ucc_slow {__be16 utpt;u8 res4[0x52 ];u8 guemr;/* UCC general extended mode register */ -u8 res5[0x200 -0x091 ]; } __attribute__ ((packed));/* QE UCC Fast */
@@ -293,21 +289,13 @@ struct ucc_fast {__be32 urtry;/* UCC retry counter register */ u8 res8[0x4C ];u8 guemr;/* UCC general extended mode register */ -u8 res9[0x100 -0x091 ]; -} __attribute__ ((packed)); - -/* QE UCC */ -struct ucc_common { -u8 res1[0x90 ]; -u8 guemr; -u8 res2[0x200 -0x091 ]; } __attribute__ ((packed));struct ucc {union {struct ucc_slow slow;struct ucc_fast fast; -struct ucc_common common; +u8 res[0x200 ];/* UCC blocks are 512 bytes each */ }; } __attribute__ ((packed));
@@ -406,7 +394,7 @@ struct dbg {/* RISC Special Registers (Trap and Breakpoint) */ struct rsp { -u8 fixme[0x100 ]; +u32 reg[0x40 ];/* 64 32-bit registers */ } __attribute__ ((packed));struct qe_immap {
@@ -435,11 +423,13 @@ struct qe_immap {u8 res13[0x600 ];struct upc upc2;/* MultiPHY UTOPIA POS Ctrlr 2*/ struct sdma sdma;/* SDMA */ -struct dbg dbg;/* Debug Space */ -struct rsp rsp[0x2 ];/* RISC Special Registers +struct dbg dbg;/* 0x104080 - 0x1040FF +Debug Space */ +struct rsp rsp[0x2 ];/* 0x104100 - 0x1042FF +RISC Special Registers (Trap and Breakpoint) */ -u8 res14[0x300 ]; -u8 res15[0x3A00 ]; +u8 res14[0x300 ];/* 0x104300 - 0x1045FF */ +u8 res15[0x3A00 ];/* 0x104600 - 0x107FFF */ u8 res16[0x8000 ];/* 0x108000 - 0x110000 */ u8 muram[0xC000 ];/* 0x110000 - 0x11C000 Multi-user RAM */
@@ -450,7 +440,7 @@ struct qe_immap {extern struct qe_immap *qe_immr;extern phys_addr_t get_qe_base (void ); -static inline unsigned long immrbar_virt_to_phys (volatile void * address) +static inline unsigned long immrbar_virt_to_phys (void *address) {if ( ((u32 )address >= (u32 )qe_immr) && ((u32 )address < ((u32 )qe_immr +QE_IMMAP_SIZE )) )
include/asm-powerpc/qe.h +168 -75
307 lines not on this page · raw message
include/asm-powerpc/ucc.h +10 -30
@@ -25,58 +25,38 @@/* Slow or fast type for UCCs. */ enum ucc_speed_type { -UCC_SPEED_TYPE_FAST ,UCC_SPEED_TYPE_SLOW -}; - -/* Initial UCCs Parameter RAM address relative to: MEM_MAP_BASE (IMMR). -*/ -enum ucc_pram_initial_offset { -UCC_PRAM_OFFSET_UCC1 =0x8400 , -UCC_PRAM_OFFSET_UCC2 =0x8500 , -UCC_PRAM_OFFSET_UCC3 =0x8600 , -UCC_PRAM_OFFSET_UCC4 =0x9000 , -UCC_PRAM_OFFSET_UCC5 =0x8000 , -UCC_PRAM_OFFSET_UCC6 =0x8100 , -UCC_PRAM_OFFSET_UCC7 =0x8200 , -UCC_PRAM_OFFSET_UCC8 =0x8300 +UCC_SPEED_TYPE_FAST =UCC_GUEMR_MODE_FAST_RX |UCC_GUEMR_MODE_FAST_TX , +UCC_SPEED_TYPE_SLOW =UCC_GUEMR_MODE_SLOW_RX |UCC_GUEMR_MODE_SLOW_TX };/* ucc_set_type * Sets UCC to slow or fast mode. * * ucc_num - (In) number of UCC (0-7). -* regs - (In) pointer to registers base for the UCC. * speed - (In) slow or fast mode for UCC. */ -int ucc_set_type (int ucc_num,struct ucc_common *regs, -enum ucc_speed_type speed); - -/* ucc_init_guemr -* Init the Guemr register. -* -* regs - (In) pointer to registers base for the UCC. -*/ -int ucc_init_guemr (struct ucc_common *regs); +int ucc_set_type (unsigned int ucc_num,enum ucc_speed_type speed); -int ucc_set_qe_mux_mii_mng (int ucc_num); +int ucc_set_qe_mux_mii_mng (unsigned int ucc_num); -int ucc_set_qe_mux_rxtx (int ucc_num,enum qe_clock clock,enum comm_dir mode); +int ucc_set_qe_mux_rxtx (unsigned int ucc_num,enum qe_clock clock, +enum comm_dir mode); -int ucc_mux_set_grant_tsa_bkpt (int ucc_num,int set,u32 mask); +int ucc_mux_set_grant_tsa_bkpt (unsigned int ucc_num,int set,u32 mask);/* QE MUX clock routing for UCC */ -static inline int ucc_set_qe_mux_grant (int ucc_num,int set) +static inline int ucc_set_qe_mux_grant (unsigned int ucc_num,int set) {return ucc_mux_set_grant_tsa_bkpt (ucc_num, set,QE_CMXUCR_GRANT ); } -static inline int ucc_set_qe_mux_tsa (int ucc_num,int set) +static inline int ucc_set_qe_mux_tsa (unsigned int ucc_num,int set) {return ucc_mux_set_grant_tsa_bkpt (ucc_num, set,QE_CMXUCR_TSA ); } -static inline int ucc_set_qe_mux_bkpt (int ucc_num,int set) +static inline int ucc_set_qe_mux_bkpt (unsigned int ucc_num,int set) {return ucc_mux_set_grant_tsa_bkpt (ucc_num, set,QE_CMXUCR_BKPT ); }
include/asm-powerpc/ucc_slow.h +5 -4
@@ -148,9 +148,10 @@ enum ucc_slow_diag_mode {struct ucc_slow_info {int ucc_num; +int protocol;/* QE_CR_PROTOCOL_xxx */ enum qe_clock rx_clock;enum qe_clock tx_clock; -u32 regs; +phys_addr_t regs;int irq;u16 uccm_mask;int data_mem_part;
@@ -186,7 +187,7 @@ struct ucc_slow_info {struct ucc_slow_private {struct ucc_slow_info *us_info; -struct ucc_slow *us_regs;/* a pointer to memory map of UCC regs */ +struct ucc_slow __iomem *us_regs;/* Ptr to memory map of UCC regs */ struct ucc_slow_pram *us_pram;/* a pointer to the parameter RAM */ u32 us_pram_offset;int enabled_tx;/* Whether channel is enabled for Tx (ENT) */
@@ -277,12 +278,12 @@ void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs);*/ void ucc_slow_stop_tx (struct ucc_slow_private * uccs); -/* ucc_slow_restart_x +/* ucc_slow_restart_tx * Restarts transmitting on a specified slow UCC. * * uccs - (In) pointer to the slow UCC structure. */ -void ucc_slow_restart_x (struct ucc_slow_private * uccs); +void ucc_slow_restart_tx (struct ucc_slow_private *uccs);u32 ucc_slow_get_qe_cr_subblock (int uccs_num);
Signature · 1 line
1.5.2.4
Quoted 1 line · Timur Tabi
This patch makes numerous miscellaneous code improvements to the QE library.
Paul and Kumar,
Unless there are any other suggestions for improvements, this is the version I'd like applied. Thanks.
Signature · 2 lines
Timur Tabi Linux Kernel Developer @ Freescale
Quoted 6 lines · Timur Tabi
Quoted 1 line · Timur Tabi
This patch makes numerous miscellaneous code improvements to the QE library.
Paul and Kumar,
Unless there are any other suggestions for improvements, this is the version I'd like applied. Thanks.
Ok, I'll take a look and see if I've got any comments.
- k
Hi Timur,
Quoted 1 line · Timur Tabi
This patch makes numerous miscellaneous code improvements to the QE library.
...and also breaks MPC8568E-MDS. ;-) Board hangs just after ip-config stuff.
Commit 589ffa1c520355e37d5868 in galak/powerpc.git.
Unfortunately it isn't split, thus it will take time to track faulty bit. But so far... maybe you have any ideas?
...
serial8250.0: ttyS1 at MMIO 0xe0004600 (irq = 42) is a 16550A RAMDISK driver initialized: 16 RAM disks of 32768K size 1024 blocksize
loop: module loaded
Gianfar MII Bus: probed
eth0: Gianfar Ethernet Controller Version 1.2, 00:e0:0c:00:00:fd
eth0: Running with NAPI enabled
eth0: 256/256 RX/TX BD ring size
eth1: Gianfar Ethernet Controller Version 1.2, 00:e0:0c:00:01:fd
eth1: Running with NAPI enabled
eth1: 256/256 RX/TX BD ring size
UCC Ethernet Controller MII Bus: probeducc_geth: QE UCC Gigabit Ethernet Controllerucc_geth: UCC1 at 0xe0082000 (irq = 32)ucc_geth: UCC2 at 0xe0083000 (irq = 33)
PCI: Enabling device 0001:02:00.0 (0000 -> 0003)
sky2 0001:02:00.0: v1.18 addr 0xa0000000 irq 18 Yukon-EC (0xb6) rev 1 sky2 eth4: addr 00:00:5a:71:75:fe
Marvell 88E1101: Registered new driver
Marvell 88E1112: Registered new driver
Marvell 88E1111: Registered new driver
Marvell 88E1145: Registered new driver
netconsole: not configured, aborting
i2c /dev entries driver
rtc-ds1374 0-0068: rtc core: registered rtc-ds1374 as rtc0
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
rtc-ds1374 0-0068: setting the system clock to 2007-01-02 22:23:42 (1167776622) sky2 eth4: enabling interface
Sending DHCP requests .<6>PHY: e0024520:02 - Link is Up - 100/Full
PHY: e0024520:03 - Link is Up - 100/Full
PHY: e0024520:01 - Link is Up - 100/Full
., OK
IP-Config: Got DHCP answer from 10.0.0.2, my address is 10.0.0.99
Thanks,
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
Quoted 11 lines · Anton Vorontsov
Hi Timur,
Quoted 1 line · Timur Tabi
This patch makes numerous miscellaneous code improvements to the QE library.
...and also breaks MPC8568E-MDS. ;-) Board hangs just after ip-config stuff.
Commit
589ffa1c520355e37d5868in galak/powerpc.git.Unfortunately it isn't split, thus it will take time to track faulty bit. But so far... maybe you have any ideas?
No. The changes are supposed to be completely transparent. I did have to modify the ucc_geth driver because of a change in some QE library functions, but I tested it on 8360 and it works there.
It could be something peripheral, like a general breakdown of the QE itself on 85xx.
Signature · 2 lines
Timur Tabi Linux Kernel Developer @ Freescale
Quoted 11 lines · Timur Tabi
Quoted 9 lines · Anton Vorontsov
Hi Timur,
Quoted 2 lines · Timur Tabi
This patch makes numerous miscellaneous code improvements to the QE library.
...and also breaks MPC8568E-MDS. ;-) Board hangs just after ip-config stuff.
Commit589ffa1c520355e37d5868in galak/powerpc.git. Unfortunately it isn't split, thus it will take time to track faulty bit. But so far... maybe you have any ideas?
Quoted 3 lines
No. The changes are supposed to be completely transparent. I did have to modify the
ucc_gethdriver because of a change in some QE library functions, but I tested it on 8360 and it works there.
I see.
Quoted 2 lines
It could be something peripheral, like a general breakdown of the QE itself on 85xx.
Doubtfully, if changes are completely transparent. Because everything works here without that cleanup.
Ok, thanks anyway, will look further as time will permit.
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
Quoted 4 lines · Anton Vorontsov
Doubtfully, if changes are completely transparent. Because everything works here without that cleanup.
Ok, thanks anyway, will look further as time will permit.
I did have one idea - the programming of the GUEMR register in ucc_fast_init() could be wrong. Can do a before/after comparison of the contents of that register?
Signature · 2 lines
Timur Tabi Linux Kernel Developer @ Freescale
Quoted 10 lines · Timur Tabi
Quoted 4 lines · Anton Vorontsov
Doubtfully, if changes are completely transparent. Because everything works here without that cleanup.
Ok, thanks anyway, will look further as time will permit.
I did have one idea - the programming of the GUEMR register in
ucc_fast_init()could be wrong. Can do a before/after comparison of the contents of that register?
I'm dropping this patch from my tree till you guys figure this out.
- k
Quoted 1 line · Anton Vorontsov
Ok, thanks anyway, will look further as time will permit.
I think I found it. Of course, if I'm right, then that doesn't explain how the 8360 works.
In struct ucc_geth, add this:
struct ucc_geth {
struct ucc_fast uccf;
+ u8 res9[0x100 - sizeof(struct ucc_fast)];
u32 maccfg1; /* mac configuration reg. 1 */
u32 maccfg2; /* mac configuration reg. 2 */
Signature · 2 lines
Timur Tabi Linux Kernel Developer @ Freescale
Quoted 11 lines · Timur Tabi
Quoted 1 line · Anton Vorontsov
Ok, thanks anyway, will look further as time will permit.
I think I found it. Of course, if I'm right, then that doesn't explain how the 8360 works.
In struct
ucc_geth, add this:struct
ucc_geth{
Review
Quoted 4 lines
(quoted diff) +1
-0struct ucc_fast uccf; + u8 res9[0x100 - sizeof(struct ucc_fast)]; u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg2; /* mac configuration reg. 2 */
This fixed issue, much thanks.
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
Quoted 8 lines · Anton Vorontsov
Review
Quoted 6 lines
struct
ucc_geth{(quoted diff) +1
-0struct ucc_fast uccf; + u8 res9[0x100 - sizeof(struct ucc_fast)]; u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg2; /* mac configuration reg. 2 */This fixed issue, much thanks.
Great! I'm very sorry about introducing that bug. I guess I didn't really test it on 8360 after all. I just thought I did.
I'm sending v4 of this patch out now.
Signature · 2 lines
Timur Tabi Linux Kernel Developer @ Freescale