Message ID | 20171113212118.10843-1-chris.brandt@renesas.com |
---|---|
State | Superseded |
Delegated to: | Marek Vasut |
Headers | show |
Series | [U-Boot] usb: r8a66597: Add support for RZ/A series | expand |
On 11/13/2017 10:21 PM, Chris Brandt wrote: > While the USB HW in the RZ/A is basically the same, there are some > differences from the original versions that were in the SH4 SoCs. > > Signed-off-by: Chris Brandt <chris.brandt@renesas.com> > --- > drivers/usb/host/r8a66597-hcd.c | 46 +++++++++++++++++++++++++++++++++++++++++ > drivers/usb/host/r8a66597.h | 25 ++++++++++++++++++++-- > 2 files changed, 69 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c > index 6ef51906c2..b28a3aebe4 100644 > --- a/drivers/usb/host/r8a66597-hcd.c > +++ b/drivers/usb/host/r8a66597-hcd.c > @@ -82,6 +82,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) > } > } while ((tmp & USBE) != USBE); > r8a66597_bclr(r8a66597, USBE, SYSCFG0); > +#ifndef RZA_USB This should be turned into Kconfig entry, some CONFIG_... > r8a66597_mdfy(r8a66597, CONFIG_R8A66597_XTAL, XTAL, SYSCFG0); > > i = 0; > @@ -94,6 +95,19 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) > return -1; > } > } while ((tmp & SCKE) != SCKE); > +#else > + /* RZ/A Only: Fix the multi-line comment, /* * foo * bar */ > + * Bits XTAL(UCKSEL) and UPLLE in SYSCFG0 for USB0 controls both USB0 > + * and USB1, so we must always set the USB0 register > + */ > +#if (CONFIG_R8A66597_XTAL == 1) > + *(u16 *)(R8A66597_BASE0) |= XTAL; Doesn't the RZ/A1 have readl()/writel()/setbits() ? > +#endif > + mdelay(1); > + *(u16 *)(R8A66597_BASE0) |= UPLLE; > + mdelay(1); > + r8a66597_bset(r8a66597, SUSPM, SUSPMODE0); > +#endif /* RZA_USB */ > #endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ > > return 0; > @@ -101,6 +115,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) > > static void r8a66597_clock_disable(struct r8a66597 *r8a66597) > { > +#ifndef RZA_USB > r8a66597_bclr(r8a66597, SCKE, SYSCFG0); > udelay(1); > #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) > @@ -108,6 +123,15 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597) > r8a66597_bclr(r8a66597, XCKE, SYSCFG0); > r8a66597_bclr(r8a66597, USBE, SYSCFG0); > #endif > +#else > + r8a66597_bclr(r8a66597, SUSPM, SUSPMODE0); > + > + *(u16 *)(R8A66597_BASE0) &= ~UPLLE; > + mdelay(1); > + r8a66597_bclr(r8a66597, USBE, SYSCFG0); > + mdelay(1); > + > +#endif > } > > static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) > @@ -118,7 +142,9 @@ static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) > r8a66597_bset(r8a66597, val, get_syscfg_reg(port)); > r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); > > +#ifndef RZA_USB > r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port)); > +#endif > } > > static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port) > @@ -148,7 +174,9 @@ static int enable_controller(struct r8a66597 *r8a66597) > if (ret < 0) > return ret; > > +#ifndef RZA_USB > r8a66597_bset(r8a66597, CONFIG_R8A66597_LDRV & LDRV, PINCFG); > +#endif > r8a66597_bset(r8a66597, USBE, SYSCFG0); > > r8a66597_bset(r8a66597, INTL, SOFCFG); > @@ -266,12 +294,30 @@ static int send_setup_packet(struct r8a66597 *r8a66597, struct usb_device *dev, > unsigned long setup_addr = USBREQ; > u16 intsts1; > int timeout = 3000; > +#ifdef RZA_USB > + u16 dcpctr; > + int timeout2 = 10000; > +#endif > u16 devsel = setup->request == USB_REQ_SET_ADDRESS ? 0 : dev->devnum; > > r8a66597_write(r8a66597, make_devsel(devsel) | > (8 << dev->maxpacketsize), DCPMAXP); > r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); > > +#ifdef RZA_USB > + dcpctr = r8a66597_read(r8a66597, DCPCTR); use wait_for_bit() . > + if ((dcpctr & PID) == PID_BUF) { > + timeout2 = 10000; > + while (!(dcpctr & BSTS)) { > + dcpctr = r8a66597_read(r8a66597, DCPCTR); > + if (timeout2-- < 0) { > + printf("DCPCTR clear timeout!\n"); > + break; > + } > + } > + } > +#endif > + > for (i = 0; i < 4; i++) { > r8a66597_write(r8a66597, le16_to_cpu(p[i]), setup_addr); > setup_addr += 2; > diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h > index 67dc3c4588..6149708ede 100644 > --- a/drivers/usb/host/r8a66597.h > +++ b/drivers/usb/host/r8a66597.h > @@ -9,6 +9,10 @@ > #ifndef __R8A66597_H__ > #define __R8A66597_H__ > > +#if defined(CONFIG_R7S72100) > +#define RZA_USB > +#endif > + > #define SYSCFG0 0x00 > #define SYSCFG1 0x02 > #define SYSSTS0 0x04 > @@ -87,8 +91,10 @@ > #define DEVADD8 0xE0 > #define DEVADD9 0xE2 > #define DEVADDA 0xE4 > +#define SUSPMODE0 0x102 /* RZ/A Only */ > > /* System Configuration Control Register */ > +#if !defined(RZA_USB) > #define XTAL 0xC000 /* b15-14: Crystal selection */ > #define XTAL48 0x8000 /* 48MHz */ > #define XTAL24 0x4000 /* 24MHz */ > @@ -98,10 +104,17 @@ > #define SCKE 0x0400 /* b10: USB clock enable */ > #define PCSDIS 0x0200 /* b9: not CS wakeup */ > #define LPSME 0x0100 /* b8: Low power sleep mode */ > +#endif > #define HSE 0x0080 /* b7: Hi-speed enable */ > #define DCFM 0x0040 /* b6: Controller function select */ > #define DRPD 0x0020 /* b5: D+/- pull down control */ > #define DPRPU 0x0010 /* b4: D+ pull up control */ > +#if defined(RZA_USB) > +#define XTAL 0x0004 /* b2: Crystal selection */ > +#define XTAL12 0x0004 /* 12MHz */ > +#define XTAL48 0x0000 /* 48MHz */ > +#define UPLLE 0x0002 /* b1: internal PLL control */ > +#endif > #define USBE 0x0001 /* b0: USB module operation enable */ > > /* System Configuration Status Register */ > @@ -173,10 +186,15 @@ > #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) > #define MBW 0x0800 > #else > +#if !defined(RZA_USB) > #define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ > +#else > +#define MBW 0x0800 /* b10: Maximum bit width for FIFO access */ > +#endif /* RZA_USB */ > #endif > #define MBW_8 0x0000 /* 8bit */ > #define MBW_16 0x0400 /* 16bit */ > +#define MBW_32 0x0800 /* 32bit */ > #define BIGEND 0x0100 /* b8: Big endian mode */ > #define BYTE_LITTLE 0x0000 /* little dendian */ > #define BYTE_BIG 0x0100 /* big endifan */ > @@ -379,6 +397,9 @@ > #define USBSPD 0x00C0 > #define RTPORT 0x0001 > > +/* Suspend Mode Register */ > +#define SUSPM 0x4000 /* b14: Suspend */ > + > #define R8A66597_MAX_NUM_PIPE 10 > #define R8A66597_BUF_BSIZE 8 > #define R8A66597_MAX_DEVICE 10 > @@ -419,7 +440,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, > int len) > { > int i; > -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) > +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) || defined(RZA_USB) > unsigned long fifoaddr = r8a66597->reg + offset; > unsigned long count; > unsigned long *p = buf; > @@ -453,7 +474,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, > { > int i; > unsigned long fifoaddr = r8a66597->reg + offset; > -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) > +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) || defined(RZA_USB) > unsigned long count; > unsigned char *pb; > unsigned long *p = buf; >
Thanks for the review. On Friday, November 17, 2017, Marek Vasut wrote: > > +#ifndef RZA_USB > > This should be turned into Kconfig entry, some CONFIG_... So you want RZA_USB in Kconfig, but is it OK if it is automatically selected when an RZ/A device is selected? For example: config R7S72100 bool select CONFIG_RZA_USB Thanks, Chris
On 11/17/2017 08:56 PM, Chris Brandt wrote: > Thanks for the review. > > On Friday, November 17, 2017, Marek Vasut wrote: >>> +#ifndef RZA_USB >> >> This should be turned into Kconfig entry, some CONFIG_... > > So you want RZA_USB in Kconfig, but is it OK if it is automatically > selected when an RZ/A device is selected? That's fine. I (well, the u-boot maintainers in general) want to move to Kconfig and drop the ad-hoc configuration with macros defined in include/configs/ at some point. > For example: > > config R7S72100 > bool > select CONFIG_RZA_USB > > Thanks, > Chris >
Hello Marek, On Friday, November 17, 2017, Marek Vasut wrote: > > +#ifdef RZA_USB > > + dcpctr = r8a66597_read(r8a66597, DCPCTR); > > use wait_for_bit() . > > > + if ((dcpctr & PID) == PID_BUF) { > > + timeout2 = 10000; > > + while (!(dcpctr & BSTS)) { > > + dcpctr = r8a66597_read(r8a66597, DCPCTR); > > + if (timeout2-- < 0) { > > + printf("DCPCTR clear timeout!\n"); > > + break; > > + } > > + } > > + } > > +#endif wait_for_bit() wants you to pass a direct address of a 32-bit register. The register I am waiting for is a 16-bit register and the hardware manual doesn't say 32-bit is allowed. When I do a 32-bit read on that address, I actually get a different value. For example: => md.w E8010060 1 e8010060: 0040 => md.l E8010060 1 e8010060: 00400000 So, I can't use wait_for_bit() Chris
On 11/27/2017 06:27 PM, Chris Brandt wrote: > Hello Marek, > > On Friday, November 17, 2017, Marek Vasut wrote: >>> +#ifdef RZA_USB >>> + dcpctr = r8a66597_read(r8a66597, DCPCTR); >> >> use wait_for_bit() . >> >>> + if ((dcpctr & PID) == PID_BUF) { >>> + timeout2 = 10000; >>> + while (!(dcpctr & BSTS)) { >>> + dcpctr = r8a66597_read(r8a66597, DCPCTR); >>> + if (timeout2-- < 0) { >>> + printf("DCPCTR clear timeout!\n"); >>> + break; >>> + } >>> + } >>> + } >>> +#endif > > > wait_for_bit() wants you to pass a direct address of a 32-bit register. > The register I am waiting for is a 16-bit register and the hardware > manual doesn't say 32-bit is allowed. > When I do a 32-bit read on that address, I actually get a different > value. > > For example: > > => md.w E8010060 1 > e8010060: 0040 > => md.l E8010060 1 > e8010060: 00400000 > > > So, I can't use wait_for_bit() Can we somehow extend wait_for_bit() ? > Chris >
On Monday, November 27, 2017 1, Marek Vasut wrote: > > wait_for_bit() wants you to pass a direct address of a 32-bit register. > > The register I am waiting for is a 16-bit register and the hardware > > manual doesn't say 32-bit is allowed. > > When I do a 32-bit read on that address, I actually get a different > > value. > > > > For example: > > > > => md.w E8010060 1 > > e8010060: 0040 > > => md.l E8010060 1 > > e8010060: 00400000 > > > > > > So, I can't use wait_for_bit() > > Can we somehow extend wait_for_bit() ? It's a nice function, so it would be good if it worked with more than just 32-bit registers. However, it's used in 98 places at the moment, so coordinating modifying all those changes at once might be an issue. Chris
On 11/28/2017 01:07 PM, Chris Brandt wrote: > On Monday, November 27, 2017 1, Marek Vasut wrote: >>> wait_for_bit() wants you to pass a direct address of a 32-bit register. >>> The register I am waiting for is a 16-bit register and the hardware >>> manual doesn't say 32-bit is allowed. >>> When I do a 32-bit read on that address, I actually get a different >>> value. >>> >>> For example: >>> >>> => md.w E8010060 1 >>> e8010060: 0040 >>> => md.l E8010060 1 >>> e8010060: 00400000 >>> >>> >>> So, I can't use wait_for_bit() >> >> Can we somehow extend wait_for_bit() ? > > It's a nice function, so it would be good if it worked with more than > just 32-bit registers. > > However, it's used in 98 places at the moment, so coordinating modifying > all those changes at once might be an issue. What about readb_poll_timeout() , would that work ? > Chris >
On Tuesday, November 28, 2017, Marek Vasut wrote: > >>> So, I can't use wait_for_bit() > >> > >> Can we somehow extend wait_for_bit() ? > > > > It's a nice function, so it would be good if it worked with more than > > just 32-bit registers. > > > > However, it's used in 98 places at the moment, so coordinating > modifying > > all those changes at once might be an issue. > > What about readb_poll_timeout() , would that work ? I just tried it out and it seems to work OK. I'll do a little more testing, and if it's still OK, I'll send a patch. Thanks, Chris
On 11/29/2017 04:28 PM, Chris Brandt wrote: > On Tuesday, November 28, 2017, Marek Vasut wrote: >>>>> So, I can't use wait_for_bit() >>>> >>>> Can we somehow extend wait_for_bit() ? >>> >>> It's a nice function, so it would be good if it worked with more than >>> just 32-bit registers. >>> >>> However, it's used in 98 places at the moment, so coordinating >> modifying >>> all those changes at once might be an issue. >> >> What about readb_poll_timeout() , would that work ? > > I just tried it out and it seems to work OK. > > I'll do a little more testing, and if it's still OK, I'll send a patch. Thanks > Thanks, > Chris >
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 6ef51906c2..b28a3aebe4 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -82,6 +82,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) } } while ((tmp & USBE) != USBE); r8a66597_bclr(r8a66597, USBE, SYSCFG0); +#ifndef RZA_USB r8a66597_mdfy(r8a66597, CONFIG_R8A66597_XTAL, XTAL, SYSCFG0); i = 0; @@ -94,6 +95,19 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) return -1; } } while ((tmp & SCKE) != SCKE); +#else + /* RZ/A Only: + * Bits XTAL(UCKSEL) and UPLLE in SYSCFG0 for USB0 controls both USB0 + * and USB1, so we must always set the USB0 register + */ +#if (CONFIG_R8A66597_XTAL == 1) + *(u16 *)(R8A66597_BASE0) |= XTAL; +#endif + mdelay(1); + *(u16 *)(R8A66597_BASE0) |= UPLLE; + mdelay(1); + r8a66597_bset(r8a66597, SUSPM, SUSPMODE0); +#endif /* RZA_USB */ #endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ return 0; @@ -101,6 +115,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) static void r8a66597_clock_disable(struct r8a66597 *r8a66597) { +#ifndef RZA_USB r8a66597_bclr(r8a66597, SCKE, SYSCFG0); udelay(1); #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) @@ -108,6 +123,15 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597) r8a66597_bclr(r8a66597, XCKE, SYSCFG0); r8a66597_bclr(r8a66597, USBE, SYSCFG0); #endif +#else + r8a66597_bclr(r8a66597, SUSPM, SUSPMODE0); + + *(u16 *)(R8A66597_BASE0) &= ~UPLLE; + mdelay(1); + r8a66597_bclr(r8a66597, USBE, SYSCFG0); + mdelay(1); + +#endif } static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) @@ -118,7 +142,9 @@ static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) r8a66597_bset(r8a66597, val, get_syscfg_reg(port)); r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); +#ifndef RZA_USB r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port)); +#endif } static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port) @@ -148,7 +174,9 @@ static int enable_controller(struct r8a66597 *r8a66597) if (ret < 0) return ret; +#ifndef RZA_USB r8a66597_bset(r8a66597, CONFIG_R8A66597_LDRV & LDRV, PINCFG); +#endif r8a66597_bset(r8a66597, USBE, SYSCFG0); r8a66597_bset(r8a66597, INTL, SOFCFG); @@ -266,12 +294,30 @@ static int send_setup_packet(struct r8a66597 *r8a66597, struct usb_device *dev, unsigned long setup_addr = USBREQ; u16 intsts1; int timeout = 3000; +#ifdef RZA_USB + u16 dcpctr; + int timeout2 = 10000; +#endif u16 devsel = setup->request == USB_REQ_SET_ADDRESS ? 0 : dev->devnum; r8a66597_write(r8a66597, make_devsel(devsel) | (8 << dev->maxpacketsize), DCPMAXP); r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); +#ifdef RZA_USB + dcpctr = r8a66597_read(r8a66597, DCPCTR); + if ((dcpctr & PID) == PID_BUF) { + timeout2 = 10000; + while (!(dcpctr & BSTS)) { + dcpctr = r8a66597_read(r8a66597, DCPCTR); + if (timeout2-- < 0) { + printf("DCPCTR clear timeout!\n"); + break; + } + } + } +#endif + for (i = 0; i < 4; i++) { r8a66597_write(r8a66597, le16_to_cpu(p[i]), setup_addr); setup_addr += 2; diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 67dc3c4588..6149708ede 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -9,6 +9,10 @@ #ifndef __R8A66597_H__ #define __R8A66597_H__ +#if defined(CONFIG_R7S72100) +#define RZA_USB +#endif + #define SYSCFG0 0x00 #define SYSCFG1 0x02 #define SYSSTS0 0x04 @@ -87,8 +91,10 @@ #define DEVADD8 0xE0 #define DEVADD9 0xE2 #define DEVADDA 0xE4 +#define SUSPMODE0 0x102 /* RZ/A Only */ /* System Configuration Control Register */ +#if !defined(RZA_USB) #define XTAL 0xC000 /* b15-14: Crystal selection */ #define XTAL48 0x8000 /* 48MHz */ #define XTAL24 0x4000 /* 24MHz */ @@ -98,10 +104,17 @@ #define SCKE 0x0400 /* b10: USB clock enable */ #define PCSDIS 0x0200 /* b9: not CS wakeup */ #define LPSME 0x0100 /* b8: Low power sleep mode */ +#endif #define HSE 0x0080 /* b7: Hi-speed enable */ #define DCFM 0x0040 /* b6: Controller function select */ #define DRPD 0x0020 /* b5: D+/- pull down control */ #define DPRPU 0x0010 /* b4: D+ pull up control */ +#if defined(RZA_USB) +#define XTAL 0x0004 /* b2: Crystal selection */ +#define XTAL12 0x0004 /* 12MHz */ +#define XTAL48 0x0000 /* 48MHz */ +#define UPLLE 0x0002 /* b1: internal PLL control */ +#endif #define USBE 0x0001 /* b0: USB module operation enable */ /* System Configuration Status Register */ @@ -173,10 +186,15 @@ #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) #define MBW 0x0800 #else +#if !defined(RZA_USB) #define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ +#else +#define MBW 0x0800 /* b10: Maximum bit width for FIFO access */ +#endif /* RZA_USB */ #endif #define MBW_8 0x0000 /* 8bit */ #define MBW_16 0x0400 /* 16bit */ +#define MBW_32 0x0800 /* 32bit */ #define BIGEND 0x0100 /* b8: Big endian mode */ #define BYTE_LITTLE 0x0000 /* little dendian */ #define BYTE_BIG 0x0100 /* big endifan */ @@ -379,6 +397,9 @@ #define USBSPD 0x00C0 #define RTPORT 0x0001 +/* Suspend Mode Register */ +#define SUSPM 0x4000 /* b14: Suspend */ + #define R8A66597_MAX_NUM_PIPE 10 #define R8A66597_BUF_BSIZE 8 #define R8A66597_MAX_DEVICE 10 @@ -419,7 +440,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, int len) { int i; -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) || defined(RZA_USB) unsigned long fifoaddr = r8a66597->reg + offset; unsigned long count; unsigned long *p = buf; @@ -453,7 +474,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, { int i; unsigned long fifoaddr = r8a66597->reg + offset; -#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) || defined(RZA_USB) unsigned long count; unsigned char *pb; unsigned long *p = buf;
While the USB HW in the RZ/A is basically the same, there are some differences from the original versions that were in the SH4 SoCs. Signed-off-by: Chris Brandt <chris.brandt@renesas.com> --- drivers/usb/host/r8a66597-hcd.c | 46 +++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/r8a66597.h | 25 ++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-)