From c53bdf1c4488ce196e9a0056285e7b4a36f6f76a Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:24 -0500 Subject: mx5: Add USB device definitions for Freescale MX51 Babbage HW This patch is part of enabling USB for Freescale MX51 Babbage HW. This patch adds device structures for USB Host1 and OTG port, and adds clocking information for USB HW. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/clock-mx51.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/mach-mx5/clock-mx51.c') diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 8f85f73b83a8..dcca330addc9 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -761,6 +761,10 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); +/* USB */ +DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET, + NULL, NULL, &pll3_sw_clk, NULL); + /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -778,6 +782,10 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) + _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk) + _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) + _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk) }; static void clk_tree_init(void) -- cgit v1.2.3 From c79504e73a0e84c4db7a2315dcdd6987b0c52566 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 10 May 2010 13:45:58 -0500 Subject: mx5: change usb clock source from pll3 to pll2 For power management reasons, pll2 should be used to source the USBOH3 clock for mx51. PLL3 can be completely gated off when USB is not used. This patch applies to 2.6.34-rc7. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/clock-mx51.c | 43 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-mx5/clock-mx51.c') diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index dcca330addc9..566cfda6185e 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -36,6 +36,7 @@ static struct clk lp_apm_clk; static struct clk periph_apm_clk; static struct clk ahb_clk; static struct clk ipg_clk; +static struct clk usboh3_clk; #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ @@ -569,6 +570,35 @@ static int _clk_uart_set_parent(struct clk *clk, struct clk *parent) return 0; } +static unsigned long clk_usboh3_get_rate(struct clk *clk) +{ + u32 reg, prediv, podf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1; + + return parent_rate / (prediv * podf); +} + +static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + static unsigned long get_high_reference_clock_rate(struct clk *clk) { return external_high_reference; @@ -690,6 +720,12 @@ static struct clk uart_root_clk = { .set_parent = _clk_uart_set_parent, }; +static struct clk usboh3_clk = { + .parent = &pll2_sw_clk, + .get_rate = clk_usboh3_get_rate, + .set_parent = _clk_usboh3_set_parent, +}; + static struct clk ahb_max_clk = { .parent = &ahb_clk, .enable_reg = MXC_CCM_CCGR0, @@ -761,10 +797,6 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); -/* USB */ -DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET, - NULL, NULL, &pll3_sw_clk, NULL); - /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -826,6 +858,9 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, clk_enable(&cpu_clk); clk_enable(&main_bus_clk); + /* set the usboh3_clk parent to pll2_sw_clk */ + clk_set_parent(&usboh3_clk, &pll2_sw_clk); + /* System timer */ mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_MXC_INT_GPT); -- cgit v1.2.3 From 2ba5a2c0d8e0f62916a885170f28786141f08f76 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 10 May 2010 13:45:59 -0500 Subject: mx5: enable usb gadget for freescale mx51 babbage board This patch enables usb gadget for freescale mx51 babbage hw. By default, the OTG port will be in device mode. To put the OTG port into Host mode, pass "otg_mode=host" in the exec command. This patch applies to 2.6.34-rc7. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/board-mx51_babbage.c | 28 +++++++++++++++++++++++++++- arch/arm/mach-mx5/clock-mx51.c | 2 ++ arch/arm/mach-mx5/devices.c | 12 ++++++++++++ arch/arm/mach-mx5/devices.h | 1 + 4 files changed, 42 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-mx5/clock-mx51.c') diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index 99f7ea903a51..dacf506f18ba 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -179,12 +180,32 @@ static struct mxc_usbh_platform_data dr_utmi_config = { .flags = MXC_EHCI_INTERNAL_PHY, }; +static struct fsl_usb2_platform_data usb_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI_WIDE, +}; + static struct mxc_usbh_platform_data usbh1_config = { .init = initialize_usbh1_port, .portsc = MXC_EHCI_MODE_ULPI, .flags = (MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_ITC_NO_THRESHOLD), }; +static int otg_mode_host; + +static int __init babbage_otg_mode(char *options) +{ + if (!strcmp(options, "host")) + otg_mode_host = 1; + else if (!strcmp(options, "device")) + otg_mode_host = 0; + else + pr_info("otg_mode neither \"host\" nor \"device\". " + "Defaulting to device\n"); + return 0; +} +__setup("otg_mode=", babbage_otg_mode); + /* * Board specific initialization. */ @@ -197,7 +218,12 @@ static void __init mxc_board_init(void) mxc_init_imx_uart(); platform_add_devices(devices, ARRAY_SIZE(devices)); - mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + if (otg_mode_host) + mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + else { + initialize_otg_port(NULL); + mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata); + } gpio_usbh1_active(); mxc_register_device(&mxc_usbh1_device, &usbh1_config); diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 566cfda6185e..9b93de36cf25 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -818,6 +818,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk) + _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) + _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) }; static void clk_tree_init(void) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index e6262f31ed8f..23850e637dc3 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -107,6 +107,18 @@ static struct resource usbotg_resources[] = { }, }; +/* OTG gadget device */ +struct platform_device mxc_usbdr_udc_device = { + .name = "fsl-usb2-udc", + .id = -1, + .num_resources = ARRAY_SIZE(usbotg_resources), + .resource = usbotg_resources, + .dev = { + .dma_mask = &usb_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + struct platform_device mxc_usbdr_host_device = { .name = "mxc-ehci", .id = 0, diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index 95c45f9e46ca..0494d6bbcc5f 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -4,3 +4,4 @@ extern struct platform_device mxc_uart_device2; extern struct platform_device mxc_fec_device; extern struct platform_device mxc_usbdr_host_device; extern struct platform_device mxc_usbh1_device; +extern struct platform_device mxc_usbdr_udc_device; -- cgit v1.2.3