linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ARM: LPC32XX: Cleanup USB clock init
@ 2012-06-20 12:01 Alexandre Pereira da Silva
  2012-06-20 13:59 ` Roland Stigge
  0 siblings, 1 reply; 2+ messages in thread
From: Alexandre Pereira da Silva @ 2012-06-20 12:01 UTC (permalink / raw)
  To: linux-arm-kernel

Move most of usb clock initialization from lpc32xx_udc and ohci-nxp to
clock.c. Also adds ohci clocks and otg clocks.

Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
---
 arch/arm/mach-lpc32xx/clock.c                 |   73 ++++++++++++++++++++++++-
 arch/arm/mach-lpc32xx/include/mach/platform.h |   14 +++++
 2 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index f6a3ffe..c80f064 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -727,14 +727,82 @@ static struct clk clk_rtc = {
 	.get_rate	= local_return_parent_rate,
 };
 
+static int local_usb_enable(struct clk *clk, int enable)
+{
+	u32 tmp;
+
+	if (enable) {
+		/* Set up I2C pull levels
+		 *
+		 * This should never be disabled as the host/gadget driver may
+		 * need to talk to the usb transceiver while the main clocks are
+		 * disabled to save power.
+		 */
+		tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
+		tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE;
+		__raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
+	}
+
+	return local_onoff_enable(clk, enable);
+}
+
 static struct clk clk_usbd = {
 	.parent		= &clk_usbpll,
-	.enable		= local_onoff_enable,
+	.enable		= local_usb_enable,
 	.enable_reg	= LPC32XX_CLKPWR_USB_CTRL,
 	.enable_mask	= LPC32XX_CLKPWR_USBCTRL_HCLK_EN,
 	.get_rate	= local_return_parent_rate,
 };
 
+#define OTG_ALWAYS_MASK		(LPC32XX_USB_OTG_OTG_CLOCK_ON | \
+				 LPC32XX_USB_OTG_I2C_CLOCK_ON)
+
+static int local_usb_otg_enable(struct clk *clk, int enable)
+{
+	int to = 1000;
+
+	if (enable) {
+		__raw_writel(clk->enable_mask, clk->enable_reg);
+
+		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
+			clk->enable_mask) != clk->enable_mask) && (to > 0))
+			to--;
+	} else {
+		__raw_writel(OTG_ALWAYS_MASK, clk->enable_reg);
+
+		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
+			OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0))
+			to--;
+	}
+
+	if (to)
+		return 0;
+	else
+		return -1;
+}
+
+static struct clk clk_usb_otg_dev = {
+	.parent		= &clk_usbpll,
+	.enable		= local_usb_otg_enable,
+	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
+	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
+			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
+			  LPC32XX_USB_OTG_DEV_CLOCK_ON |
+			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
+	.get_rate	= local_return_parent_rate,
+};
+
+static struct clk clk_usb_otg_host = {
+	.parent		= &clk_usbpll,
+	.enable		= local_usb_otg_enable,
+	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
+	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
+			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
+			  LPC32XX_USB_OTG_HOST_CLOCK_ON |
+			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
+	.get_rate	= local_return_parent_rate,
+};
+
 static int tsc_onoff_enable(struct clk *clk, int enable)
 {
 	u32 tmp;
@@ -1130,6 +1198,9 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_INIT("31060000.ethernet", NULL, &clk_net),
 	CLKDEV_INIT("dev:clcd", NULL, &clk_lcd),
 	CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd),
+	CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd),
+	CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev),
+	CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host),
 	CLKDEV_INIT("lpc32xx_rtc", NULL, &clk_rtc),
 };
 
diff --git a/arch/arm/mach-lpc32xx/include/mach/platform.h b/arch/arm/mach-lpc32xx/include/mach/platform.h
index c584f5b..acc4aab 100644
--- a/arch/arm/mach-lpc32xx/include/mach/platform.h
+++ b/arch/arm/mach-lpc32xx/include/mach/platform.h
@@ -694,4 +694,18 @@
 #define LPC32XX_GPIO_P2_MUX_CLR			_GPREG(0x02C)
 #define LPC32XX_GPIO_P2_MUX_STATE		_GPREG(0x030)
 
+/*
+ * USB Otg Registers
+ */
+#define _OTGREG(x)			io_p2v(LPC32XX_USB_OTG_BASE + (x))
+#define LPC32XX_USB_OTG_CLK_CTRL	_OTGREG(0xFF4)
+#define LPC32XX_USB_OTG_CLK_STAT	_OTGREG(0xFF8)
+
+/* USB OTG CLK CTRL bit defines */
+#define LPC32XX_USB_OTG_AHB_M_CLOCK_ON	_BIT(4)
+#define LPC32XX_USB_OTG_OTG_CLOCK_ON	_BIT(3)
+#define LPC32XX_USB_OTG_I2C_CLOCK_ON	_BIT(2)
+#define LPC32XX_USB_OTG_DEV_CLOCK_ON	_BIT(1)
+#define LPC32XX_USB_OTG_HOST_CLOCK_ON	_BIT(0)
+
 #endif
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH] ARM: LPC32XX: Cleanup USB clock init
  2012-06-20 12:01 [PATCH] ARM: LPC32XX: Cleanup USB clock init Alexandre Pereira da Silva
@ 2012-06-20 13:59 ` Roland Stigge
  0 siblings, 0 replies; 2+ messages in thread
From: Roland Stigge @ 2012-06-20 13:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/20/2012 02:01 PM, Alexandre Pereira da Silva wrote:
> Move most of usb clock initialization from lpc32xx_udc and ohci-nxp to
> clock.c. Also adds ohci clocks and otg clocks.
> 
> Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>

Acked-by: Roland Stigge <stigge@antcom.de>

> ---
>  arch/arm/mach-lpc32xx/clock.c                 |   73 ++++++++++++++++++++++++-
>  arch/arm/mach-lpc32xx/include/mach/platform.h |   14 +++++
>  2 files changed, 86 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
> index f6a3ffe..c80f064 100644
> --- a/arch/arm/mach-lpc32xx/clock.c
> +++ b/arch/arm/mach-lpc32xx/clock.c
> @@ -727,14 +727,82 @@ static struct clk clk_rtc = {
>  	.get_rate	= local_return_parent_rate,
>  };
>  
> +static int local_usb_enable(struct clk *clk, int enable)
> +{
> +	u32 tmp;
> +
> +	if (enable) {
> +		/* Set up I2C pull levels
> +		 *
> +		 * This should never be disabled as the host/gadget driver may
> +		 * need to talk to the usb transceiver while the main clocks are
> +		 * disabled to save power.
> +		 */
> +		tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
> +		tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE;
> +		__raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
> +	}
> +
> +	return local_onoff_enable(clk, enable);
> +}
> +
>  static struct clk clk_usbd = {
>  	.parent		= &clk_usbpll,
> -	.enable		= local_onoff_enable,
> +	.enable		= local_usb_enable,
>  	.enable_reg	= LPC32XX_CLKPWR_USB_CTRL,
>  	.enable_mask	= LPC32XX_CLKPWR_USBCTRL_HCLK_EN,
>  	.get_rate	= local_return_parent_rate,
>  };
>  
> +#define OTG_ALWAYS_MASK		(LPC32XX_USB_OTG_OTG_CLOCK_ON | \
> +				 LPC32XX_USB_OTG_I2C_CLOCK_ON)
> +
> +static int local_usb_otg_enable(struct clk *clk, int enable)
> +{
> +	int to = 1000;
> +
> +	if (enable) {
> +		__raw_writel(clk->enable_mask, clk->enable_reg);
> +
> +		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
> +			clk->enable_mask) != clk->enable_mask) && (to > 0))
> +			to--;
> +	} else {
> +		__raw_writel(OTG_ALWAYS_MASK, clk->enable_reg);
> +
> +		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
> +			OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0))
> +			to--;
> +	}
> +
> +	if (to)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static struct clk clk_usb_otg_dev = {
> +	.parent		= &clk_usbpll,
> +	.enable		= local_usb_otg_enable,
> +	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
> +	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
> +			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
> +			  LPC32XX_USB_OTG_DEV_CLOCK_ON |
> +			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
> +	.get_rate	= local_return_parent_rate,
> +};
> +
> +static struct clk clk_usb_otg_host = {
> +	.parent		= &clk_usbpll,
> +	.enable		= local_usb_otg_enable,
> +	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
> +	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
> +			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
> +			  LPC32XX_USB_OTG_HOST_CLOCK_ON |
> +			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
> +	.get_rate	= local_return_parent_rate,
> +};
> +
>  static int tsc_onoff_enable(struct clk *clk, int enable)
>  {
>  	u32 tmp;
> @@ -1130,6 +1198,9 @@ static struct clk_lookup lookups[] = {
>  	CLKDEV_INIT("31060000.ethernet", NULL, &clk_net),
>  	CLKDEV_INIT("dev:clcd", NULL, &clk_lcd),
>  	CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd),
> +	CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd),
> +	CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev),
> +	CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host),
>  	CLKDEV_INIT("lpc32xx_rtc", NULL, &clk_rtc),
>  };
>  
> diff --git a/arch/arm/mach-lpc32xx/include/mach/platform.h b/arch/arm/mach-lpc32xx/include/mach/platform.h
> index c584f5b..acc4aab 100644
> --- a/arch/arm/mach-lpc32xx/include/mach/platform.h
> +++ b/arch/arm/mach-lpc32xx/include/mach/platform.h
> @@ -694,4 +694,18 @@
>  #define LPC32XX_GPIO_P2_MUX_CLR			_GPREG(0x02C)
>  #define LPC32XX_GPIO_P2_MUX_STATE		_GPREG(0x030)
>  
> +/*
> + * USB Otg Registers
> + */
> +#define _OTGREG(x)			io_p2v(LPC32XX_USB_OTG_BASE + (x))
> +#define LPC32XX_USB_OTG_CLK_CTRL	_OTGREG(0xFF4)
> +#define LPC32XX_USB_OTG_CLK_STAT	_OTGREG(0xFF8)
> +
> +/* USB OTG CLK CTRL bit defines */
> +#define LPC32XX_USB_OTG_AHB_M_CLOCK_ON	_BIT(4)
> +#define LPC32XX_USB_OTG_OTG_CLOCK_ON	_BIT(3)
> +#define LPC32XX_USB_OTG_I2C_CLOCK_ON	_BIT(2)
> +#define LPC32XX_USB_OTG_DEV_CLOCK_ON	_BIT(1)
> +#define LPC32XX_USB_OTG_HOST_CLOCK_ON	_BIT(0)
> +
>  #endif

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-06-20 13:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-20 12:01 [PATCH] ARM: LPC32XX: Cleanup USB clock init Alexandre Pereira da Silva
2012-06-20 13:59 ` Roland Stigge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).