usb: lpc32xx: add host USB driver
Subsystems (4)
PATCH 3/3 usb: lpc32xx: add host USB driver
From: Sylvain Lemieux <[email protected]>
Incorporate DMA driver from legacy LPCLinux NXP BSP. The files taken from the legacy patch are:
- lpc32xx USB driver
- lpc3250 header file USB registers definition.
Updated driver to integrate with the latest u-boot:
1) Fixed checkpatch script output in legacy code.
2) Use LPC32xx definition from "cpu.h" and "clk.h".
3) Incorporate USB specific register definition from "lpc3250.h" header file from legacy BSP patch from LPCLinux.
4) Use u-boot API for register access to remove the use of volatile in register definition taken from "lpc3250.h" header file.
5) Update driver for latest u-boot USB interface (board_usb init & board_usb_cleanup).
6) Use the peripheral clock to compute the I2C divider.
The legacy BSP patch (u-boot-2009.03_lpc32x0-v1.07.patch.tar.bz2) was downloaded from the LPCLinux Web site.
--- arch/arm/include/asm/arch-lpc32xx/clk.h | 12 ++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-lpc32xx.c | 304 ++++++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 drivers/usb/host/ohci-lpc32xx.c
arch/arm/include/asm/arch-lpc32xx/clk.h +12 -0
@@ -167,6 +167,18 @@ struct clk_pm_regs {/* SDRAMCLK register bits */ #define CLK_SDRAM_DDR_SEL (1 << 1) +/* USB control register definitions */ +#define CLK_USBCTRL_PLL_STS (1 << 0) +#define CLK_USBCTRL_FDBK_PLUS1 (n) (((n) & 0xFF) << 1) +#define CLK_USBCTRL_POSTDIV_2POW (n) (((n) & 0x3) << 11) +#define CLK_USBCTRL_PLL_PWRUP (1 << 16) +#define CLK_USBCTRL_CLK_EN1 (1 << 17) +#define CLK_USBCTRL_CLK_EN2 (1 << 18) +#define CLK_USBCTRL_BUS_KEEPER (0x1 << 19) +#define CLK_USBCTRL_USBHSTND_EN (1 << 21) +#define CLK_USBCTRL_USBDVND_EN (1 << 22) +#define CLK_USBCTRL_HCLK_EN (1 << 24) +unsigned int get_sys_clk_rate (void );unsigned int get_hclk_pll_rate (void );unsigned int get_hclk_clk_div (void );
drivers/usb/host/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o obj-$(CONFIG_USB_OHCI_S3C24XX) += ohci-s3c24xx.o obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o +obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o # echi obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
drivers/usb/host/ohci-lpc32xx.c new file +304 -0
304 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH 3/3 usb: lpc32xx: add host USB driver
Quoted 1 line · slemieux.tyco at gmail.com
From: Sylvain Lemieux <[email protected]>
Hi!
Quoted 15 lines
Incorporate DMA driver from legacy LPCLinux NXP BSP. The files taken from the legacy patch are:
- lpc32xx USB driver
- lpc3250 header file USB registers definition.Updated driver to integrate with the latest u-boot:
1) Fixed checkpatch script output in legacy code.
2) Use LPC32xx definition from "cpu.h" and "clk.h".
3) Incorporate USB specific register definition from "lpc3250.h" header file from legacy BSP patch from LPCLinux.
4) Use u-boot API for register access to remove the use of volatile in register definition taken from "lpc3250.h" header file.
5) Update driver for latest u-boot USB interface (board_usbinit &board_usb_cleanup). 6) Use the peripheral clock to compute the I2C divider.
[...]
Quoted 17 lines
drivers/usb/host/ohci-lpc32xx.c new file +17
-0+static int i2c_wait_reset (int timeout) +{ +while (timeout >0 && (readl (&otg->otg_i2c.otg_i2c_ctrl) &I2C_RESET )) { +udelay (1000 ); + timeout--; + } + +return timeout <=0 ; +} + +static int isp1301_set_value (int reg,int value) +{ +int n =0 ; + +/* send isp1301 address */ +writel ((ISP1301_I2C_ADDR <<1 ) |I2C_START_BIT , + &otg->otg_i2c.otg_i2c_txrx);
drivers/usb/host/ohci-lpc32xx.c line 150
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c new file +10
-0+ +/* offset to write to */ +writel ((reg &0xff ) |I2C_WRITE , &otg->otg_i2c.otg_i2c_txrx); +/* value to write */ +writel ((value &0xff ) |I2C_STOP_BIT , &otg->otg_i2c.otg_i2c_txrx); + +/* wait for transmit done (TDI) */ +while (((readl (&otg->otg_i2c.otg_i2c_stat) &I2C_TDI ) !=I2C_TDI ) && + n++ <100000 ) + ;
Can you please rework the timeouts to use get_timer() ? It looks like this:
start = get_timer(0);
do {
if (readl(...) == FOO)
break;
udelay(1); /* Don't do tightloop and poke WDT */
} while (get_timer(start) < DELAY_IN_MSECS);drivers/usb/host/ohci-lpc32xx.c line 161
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c new file +10
-0+if (n >=100000 ) { +printf ("isp1301_set_value: ERROR TDI not set\n" ); +return -1 ; + } + +/* clear TDI */ +setbits_le32 (&otg->otg_i2c.otg_i2c_stat,I2C_TDI ); + +return 0 ; +}
Don't you want to split this code out and make it into an actual i2c controller? Then, the USB driver would use regular i2c_*() calls to configure the device on the other end of the i2c bus. That'd be really cool and convenient.
[...]
Quoted 8 lines
drivers/usb/host/ohci-lpc32xx.c new file +8
-0+int board_usb_init (int index,enum usb_init_type init) +{ +/* Remove warning. */ + (void )index; + +if (init !=USB_INIT_HOST ) +return -1 ; +
drivers/usb/host/ohci-lpc32xx.c line 252
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c new file +10
-0+/* enable AHB slave USB clock */ +setbits_le32 (&clk_pwr->usb_ctrl, +CLK_USBCTRL_HCLK_EN |CLK_USBCTRL_BUS_KEEPER ); + +/* enable I2C clock in OTG block if it isn't */ +if ((readl (&otg->otg_clk_sts) &OTG_CLK_I2C_EN ) !=OTG_CLK_I2C_EN ) { +writel (OTG_CLK_I2C_EN , &otg->otg_clk_ctrl); + +while (readl (&otg->otg_clk_sts) !=OTG_CLK_I2C_EN ) + ;
Ew..., such ugly infinite loops are a big no-no, please add a timeout here.
[...]
LEMIEUX
PATCH 3/3 usb: lpc32xx: add host USB driver
Hi Mark,
Thanks for the feedback;
Quoted 64 lines
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Marek Vasut
Sent: 17-Jul-15 6:09 PMQuoted 1 line · slemieux.tyco at gmail.com
From: Sylvain Lemieux <[email protected]>
Hi!
Quoted 15 lines
Incorporate DMA driver from legacy LPCLinux NXP BSP. The files taken from the legacy patch are:
- lpc32xx USB driver
- lpc3250 header file USB registers definition.Updated driver to integrate with the latest u-boot:
1) Fixed checkpatch script output in legacy code.
2) Use LPC32xx definition from "cpu.h" and "clk.h".
3) Incorporate USB specific register definition from "lpc3250.h" header file from legacy BSP patch from LPCLinux.
4) Use u-boot API for register access to remove the use of volatile in register definition taken from "lpc3250.h" header file.
5) Update driver for latest u-boot USB interface (board_usbinit &board_usb_cleanup). 6) Use the peripheral clock to compute the I2C divider.[...]
Quoted 17 lines
drivers/usb/host/ohci-lpc32xx.c new file +17
-0+static int i2c_wait_reset (int timeout) +{ +while (timeout >0 && (readl (&otg->otg_i2c.otg_i2c_ctrl) &I2C_RESET )) { +udelay (1000 ); + timeout--; + } + +return timeout <=0 ; +} + +static int isp1301_set_value (int reg,int value) +{ +int n =0 ; + +/* send isp1301 address */ +writel ((ISP1301_I2C_ADDR <<1 ) |I2C_START_BIT , + &otg->otg_i2c.otg_i2c_txrx);drivers/usb/host/ohci-lpc32xx.c line 150
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c new file +10
-0+ +/* offset to write to */ +writel ((reg &0xff ) |I2C_WRITE , &otg->otg_i2c.otg_i2c_txrx); +/* value to write */ +writel ((value &0xff ) |I2C_STOP_BIT , &otg->otg_i2c.otg_i2c_txrx); + +/* wait for transmit done (TDI) */ +while (((readl (&otg->otg_i2c.otg_i2c_stat) &I2C_TDI ) !=I2C_TDI ) && + n++ <100000 ) + ;Can you please rework the timeouts to use
get_timer()? It looks like this:start =
get_timer(0);do { if (readl(...) == FOO) break; udelay(1); /* Don't do tightloop and poke WDT */ } while (get_timer(start) < DELAY_IN_MSECS);
Quoted 11 lines
drivers/usb/host/ohci-lpc32xx.c line 161
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c new file +10
-0+if (n >=100000 ) { +printf ("isp1301_set_value: ERROR TDI not set\n" ); +return -1 ; + } + +/* clear TDI */ +setbits_le32 (&otg->otg_i2c.otg_i2c_stat,I2C_TDI ); + +return 0 ; +}
The initial posting was a porting effort only;
no problem, I will do the rework.
Quoted 4 lines
Don't you want to split this code out and make it into an actual i2c controller? Then, the USB driver would use regular i2c_*() calls to configure the device on the other end of the i2c bus. That'd be really cool and convenient.
I can look at this; but, I will not be able to do it before the following week. I will ensure to post my update before the merge window close.
There is already a LPC32xx I2C available in u-boot;
minor change will be require (ex. source clock is different for the USB I2C).
Quoted 14 lines
[...]
Quoted 12 lines
drivers/usb/host/ohci-lpc32xx.c new file +12
-0+int board_usb_init (int index,enum usb_init_type init) +{ +/* Remove warning. */ + (void )index; + +if (init !=USB_INIT_HOST ) +return -1 ; + +/* enable AHB slave USB clock */ +setbits_le32 (&clk_pwr->usb_ctrl, +CLK_USBCTRL_HCLK_EN |CLK_USBCTRL_BUS_KEEPER ); +
Quoted 9 lines
drivers/usb/host/ohci-lpc32xx.c line 252
Quoted 6 lines
drivers/usb/host/ohci-lpc32xx.c new file +6
-0+/* enable I2C clock in OTG block if it isn't */ +if ((readl (&otg->otg_clk_sts) &OTG_CLK_I2C_EN ) !=OTG_CLK_I2C_EN ) { +writel (OTG_CLK_I2C_EN , &otg->otg_clk_ctrl); + +while (readl (&otg->otg_clk_sts) !=OTG_CLK_I2C_EN ) + ;Ew..., such ugly infinite loops are a big no-no, please add a timeout here.
Will do as part of the rework to improve the result of this porting effort.
Sylvain
________________________________
This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.
PATCH 3/3 usb: lpc32xx: add host USB driver
Quoted 1 line · SYLVAIN
Hi Mark,
Hi!
Quoted 7 lines
Thanks for the feedback;
Quoted 5 lines
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Marek Vasut Sent: 17-Jul-15 6:09 PM
Quoted 1 line · slemieux.tyco at gmail.com
From: Sylvain Lemieux <[email protected]>
[...]
Quoted 19 lines
Quoted 19 lines
Quoted 4 lines
(quoted diff) +2
-0+ /* wait for transmit done (TDI) */ + while (((readl(&otg->otg_i2c.otg_i2c_stat) & I2C_TDI) != I2C_TDI)&& + n++ < 100000)
+ ;Can you please rework the timeouts to use
get_timer()? It looks like this:start =
get_timer(0);
do {if (readl(...) == FOO) break; udelay(1); /* Don't do tightloop and poke WDT */} while (
get_timer(start)<DELAY_IN_MSECS);
Quoted 13 lines
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c line 161
Quoted 10 lines
drivers/usb/host/ohci-lpc32xx.c new file +10
-0+if (n >=100000 ) { +printf ("isp1301_set_value: ERROR TDI not set\n" ); +return -1 ; + } + +/* clear TDI */ +setbits_le32 (&otg->otg_i2c.otg_i2c_stat,I2C_TDI ); + +return 0 ; +}The initial posting was a porting effort only;
no problem, I will do the rework.
Cool, thanks!
Quoted 7 lines
Quoted 4 lines
Don't you want to split this code out and make it into an actual i2c controller? Then, the USB driver would use regular i2c_*() calls to configure the device on the other end of the i2c bus. That'd be really cool and convenient.
I can look at this; but, I will not be able to do it before the following week. I will ensure to post my update before the merge window close.
No worries, thanks!
Quoted 3 lines
There is already a LPC32xx I2C available in u-boot;
minor change will be require (ex. source clock is different for the USB I2C).
Then that's even better, you'll have less code to take care of.
Quoted 24 lines
Quoted 15 lines
[...]
Quoted 13 lines
drivers/usb/host/ohci-lpc32xx.c new file +13
-0+int board_usb_init (int index,enum usb_init_type init) +{ +/* Remove warning. */ + (void )index; + +if (init !=USB_INIT_HOST ) +return -1 ; + +/* enable AHB slave USB clock */ +setbits_le32 (&clk_pwr->usb_ctrl, +CLK_USBCTRL_HCLK_EN |CLK_USBCTRL_BUS_KEEPER ); + +/* enable I2C clock in OTG block if it isn't */ Quoted 8 lines
drivers/usb/host/ohci-lpc32xx.c line 252
Quoted 5 lines
+ if ((
readl(&otg->otg_clk_sts)&OTG_CLK_I2C_EN) !=OTG_CLK_I2C_EN)
{ +writel(OTG_CLK_I2C_EN, &otg->otg_clk_ctrl);drivers/usb/host/ohci-lpc32xx.c new file +3
-0+ +while (readl (&otg->otg_clk_sts) !=OTG_CLK_I2C_EN ) + ;Ew..., such ugly infinite loops are a big no-no, please add a timeout here.
Quoted 1 line
Will do as part of the rework to improve the result of this porting effort.
Thanks!