OHCI: add PowerPC 440EP/440EPx support
Subsystems (2)
PATCH 1/1 OHCI: add PowerPC 440EP/440EPx support
PowerPC 440EP 440EPx OHCI controller needs frame number value shift.
--- drivers/usb/host/ohci.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/ohci.h +1 -1
@@ -612,7 +612,7 @@ static inline u32 hc32_to_cpup (const st* to arch/powerpc */ -#ifdef CONFIG_STB03xxx +#if defined(CONFIG_STB03xxx) || defined(CONFIG_440EP ) || defined(CONFIG_440EPX )#define OHCI_BE_FRAME_NO_SHIFT 16#else #define OHCI_BE_FRAME_NO_SHIFT 0
drivers/usb/host/ohci.h static inline u32 hc32_to_cpup (const st · line 618
Quoted 9 lines
drivers/usb/host/ohci.h +1
-1@@ -612,7 +612,7 @@ static inline u32 hc32_to_cpup (const st* to arch/powerpc */ -#ifdef CONFIG_STB03xxx +#if defined(CONFIG_STB03xxx) || defined(CONFIG_440EP ) || defined(CONFIG_440EPX )#define OHCI_BE_FRAME_NO_SHIFT 16#else #define OHCI_BE_FRAME_NO_SHIFT 0
Near as I can tell, the original code is wrong ... the hcca->frame_no byte offset is fully specified, so that shift should always be 16.
- Dave
Quoted 13 lines · David Brownell
drivers/usb/host/ohci.h static inline u32 hc32_to_cpup (const st · line 618
Quoted 9 lines
drivers/usb/host/ohci.h +1
-1@@ -612,7 +612,7 @@ static inline u32 hc32_to_cpup (const st* to arch/powerpc */ -#ifdef CONFIG_STB03xxx +#if defined(CONFIG_STB03xxx) || defined(CONFIG_440EP ) || defined(CONFIG_440EPX )#define OHCI_BE_FRAME_NO_SHIFT 16#else #define OHCI_BE_FRAME_NO_SHIFT 0Near as I can tell, the original code is wrong ... the
hcca->frame_nobyte offset is fully specified, so that shift should always be 16.
Quoted 2 lines
- Dave
Are you saying that it should always be #define OHCI_BE_FRAME_NO_SHIFT 16 for big endian platforms?
Quoted 5 lines
Quoted 2 lines
Near as I can tell, the original code is wrong ... the
hcca->frame_nobyte offset is fully specified, so that shift should always be 16.Are you saying that it should always be #define
OHCI_BE_FRAME_NO_SHIFT16 for big endian platforms?
More than that, I'm saying that shouldn't even be a #define! The default should be that drivers expect chips to follow the interface specs. Any value other than 16 violates the OHCI spec.
However, based on one other post, I suspect at least one Freescale part will need to declare a chip quirk for this case.
- Dave
PATCH 1/1 USB: Add frame_no big endian OHCI quirk.
Add OHCI big endian frame_no quirk.
The frame_no value stored in the HCCA is a 16 bit field at a specific offset, but since not all CPUs can do 16-bit memory accesses it's used as a 32 bit field.
And that's why big-endian OHCI will shift 16 bits, unless the spec is not followed. Currently there's one MPC52xx platform that doesn't need the shift. This case is hanled using big endian frame_no quirk.
--- drivers/usb/host/ohci-ppc-of.c | 5 ++++- drivers/usb/host/ohci.h | 13 ++++++------- 2 files changed, 10 insertions(+), 8 deletions(-)
drivers/usb/host/ohci.h +6 -7
@@ -398,6 +398,7 @@ struct ohci_hcd {#define OHCI_QUIRK_BE_MMIO 0x10/* BE registers */ #define OHCI_QUIRK_ZFMICRO 0x20/* Compaq ZFMicro chipset*/ #define OHCI_QUIRK_NEC 0x40/* lost interrupts */ +#define OHCI_QUIRK_FRAME_NO 0x80/* no big endian frame_no shift */ // there are also chip quirks/bugs in init logic struct work_struct nec_work;/* Worker for NEC quirk */
@@ -607,15 +608,12 @@ static inline u32 hc32_to_cpup (const st/* HCCA frame number is 16 bits, but is accessed as 32 bits since not all * hardware handles 16 bit reads. That creates a different confusion on * some big-endian SOC implementations. Same thing happens with PSW access. -* -* FIXME: Deal with that as a runtime quirk when STB03xxx is ported over -* to arch/powerpc */ -#ifdef CONFIG_STB03xxx -#define OHCI_BE_FRAME_NO_SHIFT 16 +#ifdef CONFIG_PPC_MPC52xx +#define big_endian_frame_no_quirk (ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO)#else -#define OHCI_BE_FRAME_NO_SHIFT 0 +#define big_endian_frame_no_quirk (ohci) 0#endif static inline u16 ohci_frame_no (const struct ohci_hcd *ohci)
@@ -623,7 +621,8 @@ static inline u16 ohci_frame_no(const stu32 tmp;if (big_endian_desc (ohci)) { tmp =be32_to_cpup ((__force __be32 *)&ohci->hcca->frame_no); - tmp >>=OHCI_BE_FRAME_NO_SHIFT ; +if (!big_endian_frame_no_quirk (ohci)) + tmp >>=16 ; }else tmp =le32_to_cpup ((__force __le32 *)&ohci->hcca->frame_no);
drivers/usb/host/ohci-ppc-of.c +4 -1
@@ -134,8 +134,11 @@ ohci_hcd_ppc_of_probe(struct of_device * } ohci =hcd_to_ohci (hcd); -if (is_bigendian) +if (is_bigendian) { ohci->flags |=OHCI_QUIRK_BE_MMIO |OHCI_QUIRK_BE_DESC ; +if (of_device_is_compatible (dn,"mpc5200-ohci" )) + ohci->flags |=OHCI_QUIRK_FRAME_NO ; + }ohci_hcd_init (ohci);
Re: [linux-usb-devel] [PATCH] USB: Add frame_no big endian OHCI quirk.
I've tested this patch only on PowerPC 440EPx Sequoia. So, this needs to be tested at least on mpc52xx. Thanks,
Valentine.
PATCH 1/1 USB: Add frame_no big endian OHCI quirk
In reply to Valentine BarshakAdd OHCI big endian frame_no quirk.
The frame_no value stored in the HCCA is a 16 bit field at a specific offset, but since not all CPUs can do 16-bit memory accesses it's used as a 32 bit field.
And that's why big-endian OHCI will shift 16 bits, unless the spec is not followed. Currently there's one MPC52xx platform that doesn't need the shift. This case is hanled using big endian frame_no quirk.
--- drivers/usb/host/ohci-ppc-of.c | 5 ++++- drivers/usb/host/ohci-ppc-soc.c | 5 +++++ drivers/usb/host/ohci.h | 13 ++++++------- 3 files changed, 15 insertions(+), 8 deletions(-)
drivers/usb/host/ohci.h +6 -7
@@ -398,6 +398,7 @@ struct ohci_hcd {#define OHCI_QUIRK_BE_MMIO 0x10/* BE registers */ #define OHCI_QUIRK_ZFMICRO 0x20/* Compaq ZFMicro chipset*/ #define OHCI_QUIRK_NEC 0x40/* lost interrupts */ +#define OHCI_QUIRK_FRAME_NO 0x80/* no big endian frame_no shift */ // there are also chip quirks/bugs in init logic struct work_struct nec_work;/* Worker for NEC quirk */
@@ -607,15 +608,12 @@ static inline u32 hc32_to_cpup (const st/* HCCA frame number is 16 bits, but is accessed as 32 bits since not all * hardware handles 16 bit reads. That creates a different confusion on * some big-endian SOC implementations. Same thing happens with PSW access. -* -* FIXME: Deal with that as a runtime quirk when STB03xxx is ported over -* to arch/powerpc */ -#ifdef CONFIG_STB03xxx -#define OHCI_BE_FRAME_NO_SHIFT 16 +#ifdef CONFIG_PPC_MPC52xx +#define big_endian_frame_no_quirk (ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO)#else -#define OHCI_BE_FRAME_NO_SHIFT 0 +#define big_endian_frame_no_quirk (ohci) 0#endif static inline u16 ohci_frame_no (const struct ohci_hcd *ohci)
@@ -623,7 +621,8 @@ static inline u16 ohci_frame_no(const stu32 tmp;if (big_endian_desc (ohci)) { tmp =be32_to_cpup ((__force __be32 *)&ohci->hcca->frame_no); - tmp >>=OHCI_BE_FRAME_NO_SHIFT ; +if (!big_endian_frame_no_quirk (ohci)) + tmp >>=16 ; }else tmp =le32_to_cpup ((__force __le32 *)&ohci->hcca->frame_no);
drivers/usb/host/ohci-ppc-of.c +4 -1
@@ -134,8 +134,11 @@ ohci_hcd_ppc_of_probe(struct of_device * } ohci =hcd_to_ohci (hcd); -if (is_bigendian) +if (is_bigendian) { ohci->flags |=OHCI_QUIRK_BE_MMIO |OHCI_QUIRK_BE_DESC ; +if (of_device_is_compatible (dn,"mpc5200-ohci" )) + ohci->flags |=OHCI_QUIRK_FRAME_NO ; + }ohci_hcd_init (ohci);
drivers/usb/host/ohci-ppc-soc.c +5 -0
@@ -73,6 +73,11 @@ static int usb_hcd_ppc_soc_probe(const s ohci =hcd_to_ohci (hcd); ohci->flags |=OHCI_QUIRK_BE_MMIO |OHCI_QUIRK_BE_DESC ; + +#ifdef CONFIG_PPC_MPC52xx +/* MPC52xx doesn't need frame_no shift */ + ohci->flags |=OHCI_QUIRK_FRAME_NO ; +#endif ohci_hcd_init (ohci); retval =usb_add_hcd (hcd, irq,IRQF_DISABLED );
Re: [linux-usb-devel] [PATCH] USB: Add frame_no big endian OHCI quirk
Quoted 10 lines · Valentine Barshak
Add OHCI big endian
frame_noquirk.
Theframe_novalue stored in the HCCA is a 16 bit field at a specific offset, but since not all CPUs can do 16-bit memory accesses it's used as a 32 bit field.
And that's why big-endian OHCI will shift 16 bits, unless the spec is not followed. Currently there's one MPC52xx platform that doesn't need the shift. This case is hanled using big endianframe_noquirk.Signed-off-by Valentine Barshak <[email protected]>
Quoted 7 lines · David Brownell
Quoted 6 lines
Quoted 3 lines
Near as I can tell, the original code is wrong ... the hcca-
Quoted 1 line
frame_nobyte offset is fully specified, so that shift should always be 16.
Are you saying that it should always be #define
OHCI_BE_FRAME_NO_SHIFT16 for big endian platforms?
Quoted 6 lines
More than that, I'm saying that shouldn't even be a #define! The default should be that drivers expect chips to follow the interface specs. Any value other than 16 violates the OHCI spec.
However, based on one other post, I suspect at least one Freescale part will need to declare a chip quirk for this case.
Which Freescale part do you think needs this?
- k
Quoted 13 lines · Kumar Gala
Quoted 10 lines · David Brownell
Quoted 5 lines
Quoted 2 lines
Near as I can tell, the original code is wrong ... the
hcca->frame_nobyte offset is fully specified, so that shift should always be 16.Are you saying that it should always be #define
OHCI_BE_FRAME_NO_SHIFT16 for big endian platforms?More than that, I'm saying that shouldn't even be a #define! The default should be that drivers expect chips to follow the interface specs. Any value other than 16 violates the OHCI spec.
Quoted 6 lines
Quoted 2 lines
However, based on one other post, I suspect at least one Freescale part will need to declare a chip quirk for this case.
Which Freescale part do you think needs this?
- k
I've looked at drivers/usb/host/Kconfig
It seems to be MPC52xx.
David, is that the one you mentioned?
Thanks,
Valentine.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
However, based on one other post, I suspect at least one Freescale part will need to declare a chip quirk for this case.
Which Freescale part do you think needs this?
I've looked at
drivers/usb/host/Kconfig
It seems to be MPC52xx.
David, is that the one you mentioned?
I wasn't the one to mention it. It was someone else in this thread.