diff options
Diffstat (limited to 'arch/mips/ath79')
-rw-r--r-- | arch/mips/ath79/clock.c | 109 | ||||
-rw-r--r-- | arch/mips/ath79/dev-usb.c | 92 | ||||
-rw-r--r-- | arch/mips/ath79/mach-db120.c | 2 |
3 files changed, 139 insertions, 64 deletions
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index b91ad3e..579f452 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -17,6 +17,8 @@ #include <linux/err.h> #include <linux/clk.h> +#include <asm/div64.h> + #include <asm/mach-ath79/ath79.h> #include <asm/mach-ath79/ar71xx_regs.h> #include "common.h" @@ -166,11 +168,34 @@ static void __init ar933x_clocks_init(void) ath79_uart_clk.rate = ath79_ref_clk.rate; } +static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, + u32 frac, u32 out_div) +{ + u64 t; + u32 ret; + + t = ath79_ref_clk.rate; + t *= nint; + do_div(t, ref_div); + ret = t; + + t = ath79_ref_clk.rate; + t *= nfrac; + do_div(t, ref_div * frac); + ret += t; + + ret /= (1 << out_div); + return ret; +} + static void __init ar934x_clocks_init(void) { - u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; + u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; u32 cpu_pll, ddr_pll; u32 bootstrap; + void __iomem *dpll_base; + + dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) @@ -178,33 +203,59 @@ static void __init ar934x_clocks_init(void) else ath79_ref_clk.rate = 25 * 1000 * 1000; - pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); - out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & - AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; - ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & - AR934X_PLL_CPU_CONFIG_REFDIV_MASK; - nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & - AR934X_PLL_CPU_CONFIG_NINT_MASK; - frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & - AR934X_PLL_CPU_CONFIG_NFRAC_MASK; - - cpu_pll = nint * ath79_ref_clk.rate / ref_div; - cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6)); - cpu_pll /= (1 << out_div); - - pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); - out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & - AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; - ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & - AR934X_PLL_DDR_CONFIG_REFDIV_MASK; - nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & - AR934X_PLL_DDR_CONFIG_NINT_MASK; - frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & - AR934X_PLL_DDR_CONFIG_NFRAC_MASK; - - ddr_pll = nint * ath79_ref_clk.rate / ref_div; - ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10)); - ddr_pll /= (1 << out_div); + pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); + if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { + out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & + AR934X_SRIF_DPLL2_OUTDIV_MASK; + pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); + nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & + AR934X_SRIF_DPLL1_NINT_MASK; + nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; + ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & + AR934X_SRIF_DPLL1_REFDIV_MASK; + frac = 1 << 18; + } else { + pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); + out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & + AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; + ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & + AR934X_PLL_CPU_CONFIG_REFDIV_MASK; + nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & + AR934X_PLL_CPU_CONFIG_NINT_MASK; + nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & + AR934X_PLL_CPU_CONFIG_NFRAC_MASK; + frac = 1 << 6; + } + + cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint, + nfrac, frac, out_div); + + pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); + if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { + out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & + AR934X_SRIF_DPLL2_OUTDIV_MASK; + pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); + nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & + AR934X_SRIF_DPLL1_NINT_MASK; + nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; + ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & + AR934X_SRIF_DPLL1_REFDIV_MASK; + frac = 1 << 18; + } else { + pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); + out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & + AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; + ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & + AR934X_PLL_DDR_CONFIG_REFDIV_MASK; + nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & + AR934X_PLL_DDR_CONFIG_NINT_MASK; + nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & + AR934X_PLL_DDR_CONFIG_NFRAC_MASK; + frac = 1 << 10; + } + + ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint, + nfrac, frac, out_div); clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); @@ -240,6 +291,8 @@ static void __init ar934x_clocks_init(void) ath79_wdt_clk.rate = ath79_ref_clk.rate; ath79_uart_clk.rate = ath79_ref_clk.rate; + + iounmap(dpll_base); } void __init ath79_clocks_init(void) diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index b2a2311..072bb9b 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c @@ -25,17 +25,7 @@ #include "common.h" #include "dev-usb.h" -static struct resource ath79_ohci_resources[] = { - [0] = { - /* .start and .end fields are filled dynamically */ - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = ATH79_MISC_IRQ_OHCI, - .end = ATH79_MISC_IRQ_OHCI, - .flags = IORESOURCE_IRQ, - }, -}; +static struct resource ath79_ohci_resources[2]; static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); @@ -54,17 +44,7 @@ static struct platform_device ath79_ohci_device = { }, }; -static struct resource ath79_ehci_resources[] = { - [0] = { - /* .start and .end fields are filled dynamically */ - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = ATH79_CPU_IRQ_USB, - .end = ATH79_CPU_IRQ_USB, - .flags = IORESOURCE_IRQ, - }, -}; +static struct resource ath79_ehci_resources[2]; static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); @@ -90,6 +70,20 @@ static struct platform_device ath79_ehci_device = { }, }; +static void __init ath79_usb_init_resource(struct resource res[2], + unsigned long base, + unsigned long size, + int irq) +{ + res[0].flags = IORESOURCE_MEM; + res[0].start = base; + res[0].end = base + size - 1; + + res[1].flags = IORESOURCE_IRQ; + res[1].start = irq; + res[1].end = irq; +} + #define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ AR71XX_RESET_USB_PHY | \ AR71XX_RESET_USB_OHCI_DLL) @@ -114,12 +108,12 @@ static void __init ath79_usb_setup(void) mdelay(900); - ath79_ohci_resources[0].start = AR71XX_OHCI_BASE; - ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1; + ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE, + AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI); platform_device_register(&ath79_ohci_device); - ath79_ehci_resources[0].start = AR71XX_EHCI_BASE; - ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1; + ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE, + AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; platform_device_register(&ath79_ehci_device); } @@ -143,10 +137,8 @@ static void __init ar7240_usb_setup(void) iounmap(usb_ctrl_base); - ath79_ohci_resources[0].start = AR7240_OHCI_BASE; - ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; - ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB; - ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB; + ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE, + AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB); platform_device_register(&ath79_ohci_device); } @@ -161,8 +153,8 @@ static void __init ar724x_usb_setup(void) ath79_device_reset_clear(AR724X_RESET_USB_PHY); mdelay(10); - ath79_ehci_resources[0].start = AR724X_EHCI_BASE; - ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1; + ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE, + AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -178,8 +170,8 @@ static void __init ar913x_usb_setup(void) ath79_device_reset_clear(AR913X_RESET_USB_PHY); mdelay(10); - ath79_ehci_resources[0].start = AR913X_EHCI_BASE; - ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1; + ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE, + AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -195,8 +187,34 @@ static void __init ar933x_usb_setup(void) ath79_device_reset_clear(AR933X_RESET_USB_PHY); mdelay(10); - ath79_ehci_resources[0].start = AR933X_EHCI_BASE; - ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1; + ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE, + AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); +} + +static void __init ar934x_usb_setup(void) +{ + u32 bootstrap; + + bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); + if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE) + return; + + ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE); + udelay(1000); + + ath79_device_reset_clear(AR934X_RESET_USB_PHY); + udelay(1000); + + ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG); + udelay(1000); + + ath79_device_reset_clear(AR934X_RESET_USB_HOST); + udelay(1000); + + ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE, + AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB); ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -213,6 +231,8 @@ void __init ath79_register_usb(void) ar913x_usb_setup(); else if (soc_is_ar933x()) ar933x_usb_setup(); + else if (soc_is_ar934x()) + ar934x_usb_setup(); else BUG(); } diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c index 1983e4d..42f540a 100644 --- a/arch/mips/ath79/mach-db120.c +++ b/arch/mips/ath79/mach-db120.c @@ -25,6 +25,7 @@ #include "dev-gpio-buttons.h" #include "dev-leds-gpio.h" #include "dev-spi.h" +#include "dev-usb.h" #include "dev-wmac.h" #include "pci.h" @@ -126,6 +127,7 @@ static void __init db120_setup(void) db120_gpio_keys); ath79_register_spi(&db120_spi_data, db120_spi_info, ARRAY_SIZE(db120_spi_info)); + ath79_register_usb(); ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); } |