at v3.4 216 lines 5.8 kB view raw
1/* 2 * Atheros AR7XXX/AR9XXX USB Host Controller device 3 * 4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * 7 * Parts of this file are based on Atheros' 2.6.15 BSP 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License version 2 as published 11 * by the Free Software Foundation. 12 */ 13 14#include <linux/kernel.h> 15#include <linux/init.h> 16#include <linux/delay.h> 17#include <linux/irq.h> 18#include <linux/dma-mapping.h> 19#include <linux/platform_device.h> 20#include <linux/usb/ehci_pdriver.h> 21#include <linux/usb/ohci_pdriver.h> 22 23#include <asm/mach-ath79/ath79.h> 24#include <asm/mach-ath79/ar71xx_regs.h> 25#include "common.h" 26#include "dev-usb.h" 27 28static struct resource ath79_ohci_resources[] = { 29 [0] = { 30 /* .start and .end fields are filled dynamically */ 31 .flags = IORESOURCE_MEM, 32 }, 33 [1] = { 34 .start = ATH79_MISC_IRQ_OHCI, 35 .end = ATH79_MISC_IRQ_OHCI, 36 .flags = IORESOURCE_IRQ, 37 }, 38}; 39 40static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); 41 42static struct usb_ohci_pdata ath79_ohci_pdata = { 43}; 44 45static struct platform_device ath79_ohci_device = { 46 .name = "ohci-platform", 47 .id = -1, 48 .resource = ath79_ohci_resources, 49 .num_resources = ARRAY_SIZE(ath79_ohci_resources), 50 .dev = { 51 .dma_mask = &ath79_ohci_dmamask, 52 .coherent_dma_mask = DMA_BIT_MASK(32), 53 .platform_data = &ath79_ohci_pdata, 54 }, 55}; 56 57static struct resource ath79_ehci_resources[] = { 58 [0] = { 59 /* .start and .end fields are filled dynamically */ 60 .flags = IORESOURCE_MEM, 61 }, 62 [1] = { 63 .start = ATH79_CPU_IRQ_USB, 64 .end = ATH79_CPU_IRQ_USB, 65 .flags = IORESOURCE_IRQ, 66 }, 67}; 68 69static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); 70 71static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { 72 .has_synopsys_hc_bug = 1, 73 .port_power_off = 1, 74}; 75 76static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { 77 .caps_offset = 0x100, 78 .has_tt = 1, 79 .port_power_off = 1, 80}; 81 82static struct platform_device ath79_ehci_device = { 83 .name = "ehci-platform", 84 .id = -1, 85 .resource = ath79_ehci_resources, 86 .num_resources = ARRAY_SIZE(ath79_ehci_resources), 87 .dev = { 88 .dma_mask = &ath79_ehci_dmamask, 89 .coherent_dma_mask = DMA_BIT_MASK(32), 90 }, 91}; 92 93#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ 94 AR71XX_RESET_USB_PHY | \ 95 AR71XX_RESET_USB_OHCI_DLL) 96 97static void __init ath79_usb_setup(void) 98{ 99 void __iomem *usb_ctrl_base; 100 101 ath79_device_reset_set(AR71XX_USB_RESET_MASK); 102 mdelay(1000); 103 ath79_device_reset_clear(AR71XX_USB_RESET_MASK); 104 105 usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE); 106 107 /* Turning on the Buff and Desc swap bits */ 108 __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG); 109 110 /* WAR for HW bug. Here it adjusts the duration between two SOFS */ 111 __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); 112 113 iounmap(usb_ctrl_base); 114 115 mdelay(900); 116 117 ath79_ohci_resources[0].start = AR71XX_OHCI_BASE; 118 ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1; 119 platform_device_register(&ath79_ohci_device); 120 121 ath79_ehci_resources[0].start = AR71XX_EHCI_BASE; 122 ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1; 123 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; 124 platform_device_register(&ath79_ehci_device); 125} 126 127static void __init ar7240_usb_setup(void) 128{ 129 void __iomem *usb_ctrl_base; 130 131 ath79_device_reset_clear(AR7240_RESET_OHCI_DLL); 132 ath79_device_reset_set(AR7240_RESET_USB_HOST); 133 134 mdelay(1000); 135 136 ath79_device_reset_set(AR7240_RESET_OHCI_DLL); 137 ath79_device_reset_clear(AR7240_RESET_USB_HOST); 138 139 usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE); 140 141 /* WAR for HW bug. Here it adjusts the duration between two SOFS */ 142 __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); 143 144 iounmap(usb_ctrl_base); 145 146 ath79_ohci_resources[0].start = AR7240_OHCI_BASE; 147 ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; 148 platform_device_register(&ath79_ohci_device); 149} 150 151static void __init ar724x_usb_setup(void) 152{ 153 ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE); 154 mdelay(10); 155 156 ath79_device_reset_clear(AR724X_RESET_USB_HOST); 157 mdelay(10); 158 159 ath79_device_reset_clear(AR724X_RESET_USB_PHY); 160 mdelay(10); 161 162 ath79_ehci_resources[0].start = AR724X_EHCI_BASE; 163 ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1; 164 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 165 platform_device_register(&ath79_ehci_device); 166} 167 168static void __init ar913x_usb_setup(void) 169{ 170 ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE); 171 mdelay(10); 172 173 ath79_device_reset_clear(AR913X_RESET_USB_HOST); 174 mdelay(10); 175 176 ath79_device_reset_clear(AR913X_RESET_USB_PHY); 177 mdelay(10); 178 179 ath79_ehci_resources[0].start = AR913X_EHCI_BASE; 180 ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1; 181 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 182 platform_device_register(&ath79_ehci_device); 183} 184 185static void __init ar933x_usb_setup(void) 186{ 187 ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE); 188 mdelay(10); 189 190 ath79_device_reset_clear(AR933X_RESET_USB_HOST); 191 mdelay(10); 192 193 ath79_device_reset_clear(AR933X_RESET_USB_PHY); 194 mdelay(10); 195 196 ath79_ehci_resources[0].start = AR933X_EHCI_BASE; 197 ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1; 198 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 199 platform_device_register(&ath79_ehci_device); 200} 201 202void __init ath79_register_usb(void) 203{ 204 if (soc_is_ar71xx()) 205 ath79_usb_setup(); 206 else if (soc_is_ar7240()) 207 ar7240_usb_setup(); 208 else if (soc_is_ar7241() || soc_is_ar7242()) 209 ar724x_usb_setup(); 210 else if (soc_is_ar913x()) 211 ar913x_usb_setup(); 212 else if (soc_is_ar933x()) 213 ar933x_usb_setup(); 214 else 215 BUG(); 216}