root/arch/mips/netlogic/xlp/usb-init-xlp2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xlp2xx_usb_ack
  2. xlp9xx_usb_ack
  3. nlm_xlpii_usb_hw_reset
  4. nlm_platform_xlpii_usb_init
  5. nlm_xlp9xx_usb_fixup_final
  6. nlm_xlp2xx_usb_fixup_final

   1 /*
   2  * Copyright (c) 2003-2013 Broadcom Corporation
   3  * All Rights Reserved
   4  *
   5  * This software is available to you under a choice of one of two
   6  * licenses.  You may choose to be licensed under the terms of the GNU
   7  * General Public License (GPL) Version 2, available from the file
   8  * COPYING in the main directory of this source tree, or the Broadcom
   9  * license below:
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  *
  15  * 1. Redistributions of source code must retain the above copyright
  16  *    notice, this list of conditions and the following disclaimer.
  17  * 2. Redistributions in binary form must reproduce the above copyright
  18  *    notice, this list of conditions and the following disclaimer in
  19  *    the documentation and/or other materials provided with the
  20  *    distribution.
  21  *
  22  * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
  23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25  * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
  26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  29  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  31  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  32  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33  */
  34 
  35 #include <linux/dma-mapping.h>
  36 #include <linux/kernel.h>
  37 #include <linux/delay.h>
  38 #include <linux/init.h>
  39 #include <linux/pci.h>
  40 #include <linux/pci_ids.h>
  41 #include <linux/platform_device.h>
  42 #include <linux/irq.h>
  43 
  44 #include <asm/netlogic/common.h>
  45 #include <asm/netlogic/haldefs.h>
  46 #include <asm/netlogic/xlp-hal/iomap.h>
  47 #include <asm/netlogic/xlp-hal/xlp.h>
  48 
  49 #define XLPII_USB3_CTL_0                0xc0
  50 #define XLPII_VAUXRST                   BIT(0)
  51 #define XLPII_VCCRST                    BIT(1)
  52 #define XLPII_NUM2PORT                  9
  53 #define XLPII_NUM3PORT                  13
  54 #define XLPII_RTUNEREQ                  BIT(20)
  55 #define XLPII_MS_CSYSREQ                BIT(21)
  56 #define XLPII_XS_CSYSREQ                BIT(22)
  57 #define XLPII_RETENABLEN                BIT(23)
  58 #define XLPII_TX2RX                     BIT(24)
  59 #define XLPII_XHCIREV                   BIT(25)
  60 #define XLPII_ECCDIS                    BIT(26)
  61 
  62 #define XLPII_USB3_INT_REG              0xc2
  63 #define XLPII_USB3_INT_MASK             0xc3
  64 
  65 #define XLPII_USB_PHY_TEST              0xc6
  66 #define XLPII_PRESET                    BIT(0)
  67 #define XLPII_ATERESET                  BIT(1)
  68 #define XLPII_LOOPEN                    BIT(2)
  69 #define XLPII_TESTPDHSP                 BIT(3)
  70 #define XLPII_TESTPDSSP                 BIT(4)
  71 #define XLPII_TESTBURNIN                BIT(5)
  72 
  73 #define XLPII_USB_PHY_LOS_LV            0xc9
  74 #define XLPII_LOSLEV                    0
  75 #define XLPII_LOSBIAS                   5
  76 #define XLPII_SQRXTX                    8
  77 #define XLPII_TXBOOST                   11
  78 #define XLPII_RSLKSEL                   16
  79 #define XLPII_FSEL                      20
  80 
  81 #define XLPII_USB_RFCLK_REG             0xcc
  82 #define XLPII_VVLD                      30
  83 
  84 #define nlm_read_usb_reg(b, r)          nlm_read_reg(b, r)
  85 #define nlm_write_usb_reg(b, r, v)      nlm_write_reg(b, r, v)
  86 
  87 #define nlm_xlpii_get_usb_pcibase(node, inst)                   \
  88                         nlm_pcicfg_base(cpu_is_xlp9xx() ?       \
  89                         XLP9XX_IO_USB_OFFSET(node, inst) :      \
  90                         XLP2XX_IO_USB_OFFSET(node, inst))
  91 #define nlm_xlpii_get_usb_regbase(node, inst)           \
  92         (nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
  93 
  94 static void xlp2xx_usb_ack(struct irq_data *data)
  95 {
  96         u64 port_addr;
  97 
  98         switch (data->irq) {
  99         case PIC_2XX_XHCI_0_IRQ:
 100                 port_addr = nlm_xlpii_get_usb_regbase(0, 1);
 101                 break;
 102         case PIC_2XX_XHCI_1_IRQ:
 103                 port_addr = nlm_xlpii_get_usb_regbase(0, 2);
 104                 break;
 105         case PIC_2XX_XHCI_2_IRQ:
 106                 port_addr = nlm_xlpii_get_usb_regbase(0, 3);
 107                 break;
 108         default:
 109                 pr_err("No matching USB irq!\n");
 110                 return;
 111         }
 112         nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
 113 }
 114 
 115 static void xlp9xx_usb_ack(struct irq_data *data)
 116 {
 117         u64 port_addr;
 118         int node, irq;
 119 
 120         /* Find the node and irq on the node */
 121         irq = data->irq % NLM_IRQS_PER_NODE;
 122         node = data->irq / NLM_IRQS_PER_NODE;
 123 
 124         switch (irq) {
 125         case PIC_9XX_XHCI_0_IRQ:
 126                 port_addr = nlm_xlpii_get_usb_regbase(node, 1);
 127                 break;
 128         case PIC_9XX_XHCI_1_IRQ:
 129                 port_addr = nlm_xlpii_get_usb_regbase(node, 2);
 130                 break;
 131         case PIC_9XX_XHCI_2_IRQ:
 132                 port_addr = nlm_xlpii_get_usb_regbase(node, 3);
 133                 break;
 134         default:
 135                 pr_err("No matching USB irq %d node  %d!\n", irq, node);
 136                 return;
 137         }
 138         nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
 139 }
 140 
 141 static void nlm_xlpii_usb_hw_reset(int node, int port)
 142 {
 143         u64 port_addr, xhci_base, pci_base;
 144         void __iomem *corebase;
 145         u32 val;
 146 
 147         port_addr = nlm_xlpii_get_usb_regbase(node, port);
 148 
 149         /* Set frequency */
 150         val = nlm_read_usb_reg(port_addr, XLPII_USB_PHY_LOS_LV);
 151         val &= ~(0x3f << XLPII_FSEL);
 152         val |= (0x27 << XLPII_FSEL);
 153         nlm_write_usb_reg(port_addr, XLPII_USB_PHY_LOS_LV, val);
 154 
 155         val = nlm_read_usb_reg(port_addr, XLPII_USB_RFCLK_REG);
 156         val |= (1 << XLPII_VVLD);
 157         nlm_write_usb_reg(port_addr, XLPII_USB_RFCLK_REG, val);
 158 
 159         /* PHY reset */
 160         val = nlm_read_usb_reg(port_addr, XLPII_USB_PHY_TEST);
 161         val &= (XLPII_ATERESET | XLPII_LOOPEN | XLPII_TESTPDHSP
 162                 | XLPII_TESTPDSSP | XLPII_TESTBURNIN);
 163         nlm_write_usb_reg(port_addr, XLPII_USB_PHY_TEST, val);
 164 
 165         /* Setup control register */
 166         val =  XLPII_VAUXRST | XLPII_VCCRST | (1 << XLPII_NUM2PORT)
 167                 | (1 << XLPII_NUM3PORT) | XLPII_MS_CSYSREQ | XLPII_XS_CSYSREQ
 168                 | XLPII_RETENABLEN | XLPII_XHCIREV;
 169         nlm_write_usb_reg(port_addr, XLPII_USB3_CTL_0, val);
 170 
 171         /* Enable interrupts */
 172         nlm_write_usb_reg(port_addr, XLPII_USB3_INT_MASK, 0x00000001);
 173 
 174         /* Clear all interrupts */
 175         nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
 176 
 177         udelay(2000);
 178 
 179         /* XHCI configuration at PCI mem */
 180         pci_base = nlm_xlpii_get_usb_pcibase(node, port);
 181         xhci_base = nlm_read_usb_reg(pci_base, 0x4) & ~0xf;
 182         corebase = ioremap(xhci_base, 0x10000);
 183         if (!corebase)
 184                 return;
 185 
 186         writel(0x240002, corebase + 0xc2c0);
 187         /* GCTL 0xc110 */
 188         val = readl(corebase + 0xc110);
 189         val &= ~(0x3 << 12);
 190         val |= (1 << 12);
 191         writel(val, corebase + 0xc110);
 192         udelay(100);
 193 
 194         /* PHYCFG 0xc200 */
 195         val = readl(corebase + 0xc200);
 196         val &= ~(1 << 6);
 197         writel(val, corebase + 0xc200);
 198         udelay(100);
 199 
 200         /* PIPECTL 0xc2c0 */
 201         val = readl(corebase + 0xc2c0);
 202         val &= ~(1 << 17);
 203         writel(val, corebase + 0xc2c0);
 204 
 205         iounmap(corebase);
 206 }
 207 
 208 static int __init nlm_platform_xlpii_usb_init(void)
 209 {
 210         int node;
 211 
 212         if (!cpu_is_xlpii())
 213                 return 0;
 214 
 215         if (!cpu_is_xlp9xx()) {
 216                 /* XLP 2XX single node */
 217                 pr_info("Initializing 2XX USB Interface\n");
 218                 nlm_xlpii_usb_hw_reset(0, 1);
 219                 nlm_xlpii_usb_hw_reset(0, 2);
 220                 nlm_xlpii_usb_hw_reset(0, 3);
 221                 nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlp2xx_usb_ack);
 222                 nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlp2xx_usb_ack);
 223                 nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlp2xx_usb_ack);
 224                 return 0;
 225         }
 226 
 227         /* XLP 9XX, multi-node */
 228         pr_info("Initializing 9XX/5XX USB Interface\n");
 229         for (node = 0; node < NLM_NR_NODES; node++) {
 230                 if (!nlm_node_present(node))
 231                         continue;
 232                 nlm_xlpii_usb_hw_reset(node, 1);
 233                 nlm_xlpii_usb_hw_reset(node, 2);
 234                 nlm_xlpii_usb_hw_reset(node, 3);
 235                 nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_0_IRQ, xlp9xx_usb_ack);
 236                 nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_1_IRQ, xlp9xx_usb_ack);
 237                 nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_2_IRQ, xlp9xx_usb_ack);
 238         }
 239         return 0;
 240 }
 241 
 242 arch_initcall(nlm_platform_xlpii_usb_init);
 243 
 244 static u64 xlp_usb_dmamask = ~(u32)0;
 245 
 246 /* Fixup the IRQ for USB devices which is exist on XLP9XX SOC PCIE bus */
 247 static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev)
 248 {
 249         int node;
 250 
 251         node = xlp_socdev_to_node(dev);
 252         dev->dev.dma_mask               = &xlp_usb_dmamask;
 253         dev->dev.coherent_dma_mask      = DMA_BIT_MASK(32);
 254         switch (dev->devfn) {
 255         case 0x21:
 256                 dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_0_IRQ);
 257                 break;
 258         case 0x22:
 259                 dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_1_IRQ);
 260                 break;
 261         case 0x23:
 262                 dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_2_IRQ);
 263                 break;
 264         }
 265 }
 266 
 267 /* Fixup the IRQ for USB devices which is exist on XLP2XX SOC PCIE bus */
 268 static void nlm_xlp2xx_usb_fixup_final(struct pci_dev *dev)
 269 {
 270         dev->dev.dma_mask               = &xlp_usb_dmamask;
 271         dev->dev.coherent_dma_mask      = DMA_BIT_MASK(32);
 272         switch (dev->devfn) {
 273         case 0x21:
 274                 dev->irq = PIC_2XX_XHCI_0_IRQ;
 275                 break;
 276         case 0x22:
 277                 dev->irq = PIC_2XX_XHCI_1_IRQ;
 278                 break;
 279         case 0x23:
 280                 dev->irq = PIC_2XX_XHCI_2_IRQ;
 281                 break;
 282         }
 283 }
 284 
 285 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_XHCI,
 286                 nlm_xlp9xx_usb_fixup_final);
 287 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI,
 288                 nlm_xlp2xx_usb_fixup_final);

/* [<][>][^][v][top][bottom][index][help] */