at v3.7 238 lines 6.3 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[2]; 29 30static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); 31 32static struct usb_ohci_pdata ath79_ohci_pdata = { 33}; 34 35static struct platform_device ath79_ohci_device = { 36 .name = "ohci-platform", 37 .id = -1, 38 .resource = ath79_ohci_resources, 39 .num_resources = ARRAY_SIZE(ath79_ohci_resources), 40 .dev = { 41 .dma_mask = &ath79_ohci_dmamask, 42 .coherent_dma_mask = DMA_BIT_MASK(32), 43 .platform_data = &ath79_ohci_pdata, 44 }, 45}; 46 47static struct resource ath79_ehci_resources[2]; 48 49static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); 50 51static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { 52 .has_synopsys_hc_bug = 1, 53 .port_power_off = 1, 54}; 55 56static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { 57 .caps_offset = 0x100, 58 .has_tt = 1, 59 .port_power_off = 1, 60}; 61 62static struct platform_device ath79_ehci_device = { 63 .name = "ehci-platform", 64 .id = -1, 65 .resource = ath79_ehci_resources, 66 .num_resources = ARRAY_SIZE(ath79_ehci_resources), 67 .dev = { 68 .dma_mask = &ath79_ehci_dmamask, 69 .coherent_dma_mask = DMA_BIT_MASK(32), 70 }, 71}; 72 73static void __init ath79_usb_init_resource(struct resource res[2], 74 unsigned long base, 75 unsigned long size, 76 int irq) 77{ 78 res[0].flags = IORESOURCE_MEM; 79 res[0].start = base; 80 res[0].end = base + size - 1; 81 82 res[1].flags = IORESOURCE_IRQ; 83 res[1].start = irq; 84 res[1].end = irq; 85} 86 87#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ 88 AR71XX_RESET_USB_PHY | \ 89 AR71XX_RESET_USB_OHCI_DLL) 90 91static void __init ath79_usb_setup(void) 92{ 93 void __iomem *usb_ctrl_base; 94 95 ath79_device_reset_set(AR71XX_USB_RESET_MASK); 96 mdelay(1000); 97 ath79_device_reset_clear(AR71XX_USB_RESET_MASK); 98 99 usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE); 100 101 /* Turning on the Buff and Desc swap bits */ 102 __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG); 103 104 /* WAR for HW bug. Here it adjusts the duration between two SOFS */ 105 __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); 106 107 iounmap(usb_ctrl_base); 108 109 mdelay(900); 110 111 ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE, 112 AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI); 113 platform_device_register(&ath79_ohci_device); 114 115 ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE, 116 AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB); 117 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; 118 platform_device_register(&ath79_ehci_device); 119} 120 121static void __init ar7240_usb_setup(void) 122{ 123 void __iomem *usb_ctrl_base; 124 125 ath79_device_reset_clear(AR7240_RESET_OHCI_DLL); 126 ath79_device_reset_set(AR7240_RESET_USB_HOST); 127 128 mdelay(1000); 129 130 ath79_device_reset_set(AR7240_RESET_OHCI_DLL); 131 ath79_device_reset_clear(AR7240_RESET_USB_HOST); 132 133 usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE); 134 135 /* WAR for HW bug. Here it adjusts the duration between two SOFS */ 136 __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); 137 138 iounmap(usb_ctrl_base); 139 140 ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE, 141 AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB); 142 platform_device_register(&ath79_ohci_device); 143} 144 145static void __init ar724x_usb_setup(void) 146{ 147 ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE); 148 mdelay(10); 149 150 ath79_device_reset_clear(AR724X_RESET_USB_HOST); 151 mdelay(10); 152 153 ath79_device_reset_clear(AR724X_RESET_USB_PHY); 154 mdelay(10); 155 156 ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE, 157 AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB); 158 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 159 platform_device_register(&ath79_ehci_device); 160} 161 162static void __init ar913x_usb_setup(void) 163{ 164 ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE); 165 mdelay(10); 166 167 ath79_device_reset_clear(AR913X_RESET_USB_HOST); 168 mdelay(10); 169 170 ath79_device_reset_clear(AR913X_RESET_USB_PHY); 171 mdelay(10); 172 173 ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE, 174 AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB); 175 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 176 platform_device_register(&ath79_ehci_device); 177} 178 179static void __init ar933x_usb_setup(void) 180{ 181 ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE); 182 mdelay(10); 183 184 ath79_device_reset_clear(AR933X_RESET_USB_HOST); 185 mdelay(10); 186 187 ath79_device_reset_clear(AR933X_RESET_USB_PHY); 188 mdelay(10); 189 190 ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE, 191 AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB); 192 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 193 platform_device_register(&ath79_ehci_device); 194} 195 196static void __init ar934x_usb_setup(void) 197{ 198 u32 bootstrap; 199 200 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 201 if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE) 202 return; 203 204 ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE); 205 udelay(1000); 206 207 ath79_device_reset_clear(AR934X_RESET_USB_PHY); 208 udelay(1000); 209 210 ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG); 211 udelay(1000); 212 213 ath79_device_reset_clear(AR934X_RESET_USB_HOST); 214 udelay(1000); 215 216 ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE, 217 AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB); 218 ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; 219 platform_device_register(&ath79_ehci_device); 220} 221 222void __init ath79_register_usb(void) 223{ 224 if (soc_is_ar71xx()) 225 ath79_usb_setup(); 226 else if (soc_is_ar7240()) 227 ar7240_usb_setup(); 228 else if (soc_is_ar7241() || soc_is_ar7242()) 229 ar724x_usb_setup(); 230 else if (soc_is_ar913x()) 231 ar913x_usb_setup(); 232 else if (soc_is_ar933x()) 233 ar933x_usb_setup(); 234 else if (soc_is_ar934x()) 235 ar934x_usb_setup(); 236 else 237 BUG(); 238}