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