18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2003-2012 Broadcom Corporation 38c2ecf20Sopenharmony_ci * All Rights Reserved 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two 68c2ecf20Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 78c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 88c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the Broadcom 98c2ecf20Sopenharmony_ci * license below: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 128c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 138c2ecf20Sopenharmony_ci * are met: 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 168c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 178c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 188c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 198c2ecf20Sopenharmony_ci * the documentation and/or other materials provided with the 208c2ecf20Sopenharmony_ci * distribution. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 238c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 248c2ecf20Sopenharmony_ci * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 258c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 268c2ecf20Sopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 278c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 288c2ecf20Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 298c2ecf20Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 308c2ecf20Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 318c2ecf20Sopenharmony_ci * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 328c2ecf20Sopenharmony_ci * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 368c2ecf20Sopenharmony_ci#include <linux/kernel.h> 378c2ecf20Sopenharmony_ci#include <linux/delay.h> 388c2ecf20Sopenharmony_ci#include <linux/init.h> 398c2ecf20Sopenharmony_ci#include <linux/pci.h> 408c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#include <asm/netlogic/haldefs.h> 438c2ecf20Sopenharmony_ci#include <asm/netlogic/xlp-hal/iomap.h> 448c2ecf20Sopenharmony_ci#include <asm/netlogic/xlp-hal/xlp.h> 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* 478c2ecf20Sopenharmony_ci * USB glue logic registers, used only during initialization 488c2ecf20Sopenharmony_ci */ 498c2ecf20Sopenharmony_ci#define USB_CTL_0 0x01 508c2ecf20Sopenharmony_ci#define USB_PHY_0 0x0A 518c2ecf20Sopenharmony_ci#define USB_PHY_RESET 0x01 528c2ecf20Sopenharmony_ci#define USB_PHY_PORT_RESET_0 0x10 538c2ecf20Sopenharmony_ci#define USB_PHY_PORT_RESET_1 0x20 548c2ecf20Sopenharmony_ci#define USB_CONTROLLER_RESET 0x01 558c2ecf20Sopenharmony_ci#define USB_INT_STATUS 0x0E 568c2ecf20Sopenharmony_ci#define USB_INT_EN 0x0F 578c2ecf20Sopenharmony_ci#define USB_PHY_INTERRUPT_EN 0x01 588c2ecf20Sopenharmony_ci#define USB_OHCI_INTERRUPT_EN 0x02 598c2ecf20Sopenharmony_ci#define USB_OHCI_INTERRUPT1_EN 0x04 608c2ecf20Sopenharmony_ci#define USB_OHCI_INTERRUPT2_EN 0x08 618c2ecf20Sopenharmony_ci#define USB_CTRL_INTERRUPT_EN 0x10 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#define nlm_read_usb_reg(b, r) nlm_read_reg(b, r) 648c2ecf20Sopenharmony_ci#define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v) 658c2ecf20Sopenharmony_ci#define nlm_get_usb_pcibase(node, inst) \ 668c2ecf20Sopenharmony_ci nlm_pcicfg_base(XLP_IO_USB_OFFSET(node, inst)) 678c2ecf20Sopenharmony_ci#define nlm_get_usb_regbase(node, inst) \ 688c2ecf20Sopenharmony_ci (nlm_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic void nlm_usb_intr_en(int node, int port) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci uint32_t val; 738c2ecf20Sopenharmony_ci uint64_t port_addr; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci port_addr = nlm_get_usb_regbase(node, port); 768c2ecf20Sopenharmony_ci val = nlm_read_usb_reg(port_addr, USB_INT_EN); 778c2ecf20Sopenharmony_ci val = USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT_EN | 788c2ecf20Sopenharmony_ci USB_OHCI_INTERRUPT1_EN | USB_OHCI_INTERRUPT2_EN; 798c2ecf20Sopenharmony_ci nlm_write_usb_reg(port_addr, USB_INT_EN, val); 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic void nlm_usb_hw_reset(int node, int port) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci uint64_t port_addr; 858c2ecf20Sopenharmony_ci uint32_t val; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci /* reset USB phy */ 888c2ecf20Sopenharmony_ci port_addr = nlm_get_usb_regbase(node, port); 898c2ecf20Sopenharmony_ci val = nlm_read_usb_reg(port_addr, USB_PHY_0); 908c2ecf20Sopenharmony_ci val &= ~(USB_PHY_RESET | USB_PHY_PORT_RESET_0 | USB_PHY_PORT_RESET_1); 918c2ecf20Sopenharmony_ci nlm_write_usb_reg(port_addr, USB_PHY_0, val); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci mdelay(100); 948c2ecf20Sopenharmony_ci val = nlm_read_usb_reg(port_addr, USB_CTL_0); 958c2ecf20Sopenharmony_ci val &= ~(USB_CONTROLLER_RESET); 968c2ecf20Sopenharmony_ci val |= 0x4; 978c2ecf20Sopenharmony_ci nlm_write_usb_reg(port_addr, USB_CTL_0, val); 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic int __init nlm_platform_usb_init(void) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci if (cpu_is_xlpii()) 1038c2ecf20Sopenharmony_ci return 0; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci pr_info("Initializing USB Interface\n"); 1068c2ecf20Sopenharmony_ci nlm_usb_hw_reset(0, 0); 1078c2ecf20Sopenharmony_ci nlm_usb_hw_reset(0, 3); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci /* Enable PHY interrupts */ 1108c2ecf20Sopenharmony_ci nlm_usb_intr_en(0, 0); 1118c2ecf20Sopenharmony_ci nlm_usb_intr_en(0, 3); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci return 0; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ciarch_initcall(nlm_platform_usb_init); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic u64 xlp_usb_dmamask = ~(u32)0; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* Fixup the IRQ for USB devices which is exist on XLP SOC PCIE bus */ 1218c2ecf20Sopenharmony_cistatic void nlm_usb_fixup_final(struct pci_dev *dev) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci dev->dev.dma_mask = &xlp_usb_dmamask; 1248c2ecf20Sopenharmony_ci dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 1258c2ecf20Sopenharmony_ci switch (dev->devfn) { 1268c2ecf20Sopenharmony_ci case 0x10: 1278c2ecf20Sopenharmony_ci dev->irq = PIC_EHCI_0_IRQ; 1288c2ecf20Sopenharmony_ci break; 1298c2ecf20Sopenharmony_ci case 0x11: 1308c2ecf20Sopenharmony_ci dev->irq = PIC_OHCI_0_IRQ; 1318c2ecf20Sopenharmony_ci break; 1328c2ecf20Sopenharmony_ci case 0x12: 1338c2ecf20Sopenharmony_ci dev->irq = PIC_OHCI_1_IRQ; 1348c2ecf20Sopenharmony_ci break; 1358c2ecf20Sopenharmony_ci case 0x13: 1368c2ecf20Sopenharmony_ci dev->irq = PIC_EHCI_1_IRQ; 1378c2ecf20Sopenharmony_ci break; 1388c2ecf20Sopenharmony_ci case 0x14: 1398c2ecf20Sopenharmony_ci dev->irq = PIC_OHCI_2_IRQ; 1408c2ecf20Sopenharmony_ci break; 1418c2ecf20Sopenharmony_ci case 0x15: 1428c2ecf20Sopenharmony_ci dev->irq = PIC_OHCI_3_IRQ; 1438c2ecf20Sopenharmony_ci break; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ciDECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_EHCI, 1478c2ecf20Sopenharmony_ci nlm_usb_fixup_final); 1488c2ecf20Sopenharmony_ciDECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_OHCI, 1498c2ecf20Sopenharmony_ci nlm_usb_fixup_final); 150