1 /*- 2 * Copyright (c) 2007-2008, Juniper Networks, Inc. 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: GPL-2.0 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <pci.h> 12 #include <usb.h> 13 #include <asm/io.h> 14 15 #include "ehci.h" 16 17 /* Information about a USB port */ 18 struct ehci_pci_priv { 19 struct ehci_ctrl ehci; 20 struct phy phy; 21 }; 22 23 #if CONFIG_IS_ENABLED(DM_USB) 24 static int ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr, 25 struct ehci_hcor **ret_hcor) 26 { 27 struct ehci_pci_priv *priv = dev_get_priv(dev); 28 struct ehci_hccr *hccr; 29 struct ehci_hcor *hcor; 30 int ret; 31 u32 cmd; 32 33 ret = ehci_setup_phy(dev, &priv->phy, 0); 34 if (ret) 35 return ret; 36 37 hccr = (struct ehci_hccr *)dm_pci_map_bar(dev, 38 PCI_BASE_ADDRESS_0, PCI_REGION_MEM); 39 hcor = (struct ehci_hcor *)((uintptr_t) hccr + 40 HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 41 42 debug("EHCI-PCI init hccr %#lx and hcor %#lx hc_length %d\n", 43 (ulong)hccr, (ulong)hcor, 44 (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 45 46 *ret_hccr = hccr; 47 *ret_hcor = hcor; 48 49 /* enable busmaster */ 50 dm_pci_read_config32(dev, PCI_COMMAND, &cmd); 51 cmd |= PCI_COMMAND_MASTER; 52 dm_pci_write_config32(dev, PCI_COMMAND, cmd); 53 54 return 0; 55 } 56 57 #else 58 59 #ifdef CONFIG_PCI_EHCI_DEVICE 60 static struct pci_device_id ehci_pci_ids[] = { 61 /* Please add supported PCI EHCI controller ids here */ 62 {0x1033, 0x00E0}, /* NEC */ 63 {0x10B9, 0x5239}, /* ULI1575 PCI EHCI module ids */ 64 {0x12D8, 0x400F}, /* Pericom */ 65 {0, 0} 66 }; 67 #endif 68 69 static void ehci_pci_legacy_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr, 70 struct ehci_hcor **ret_hcor) 71 { 72 struct ehci_hccr *hccr; 73 struct ehci_hcor *hcor; 74 u32 cmd; 75 76 hccr = (struct ehci_hccr *)pci_map_bar(pdev, 77 PCI_BASE_ADDRESS_0, PCI_REGION_MEM); 78 hcor = (struct ehci_hcor *)((uintptr_t) hccr + 79 HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 80 81 debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", 82 (u32)hccr, (u32)hcor, 83 (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 84 85 *ret_hccr = hccr; 86 *ret_hcor = hcor; 87 88 /* enable busmaster */ 89 pci_read_config_dword(pdev, PCI_COMMAND, &cmd); 90 cmd |= PCI_COMMAND_MASTER; 91 pci_write_config_dword(pdev, PCI_COMMAND, cmd); 92 } 93 94 /* 95 * Create the appropriate control structures to manage 96 * a new EHCI host controller. 97 */ 98 int ehci_hcd_init(int index, enum usb_init_type init, 99 struct ehci_hccr **ret_hccr, struct ehci_hcor **ret_hcor) 100 { 101 pci_dev_t pdev; 102 103 #ifdef CONFIG_PCI_EHCI_DEVICE 104 pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE); 105 #else 106 pdev = pci_find_class(PCI_CLASS_SERIAL_USB_EHCI, index); 107 #endif 108 if (pdev < 0) { 109 printf("EHCI host controller not found\n"); 110 return -1; 111 } 112 ehci_pci_legacy_init(pdev, ret_hccr, ret_hcor); 113 114 return 0; 115 } 116 117 /* 118 * Destroy the appropriate control structures corresponding 119 * the the EHCI host controller. 120 */ 121 int ehci_hcd_stop(int index) 122 { 123 return 0; 124 } 125 #endif /* !CONFIG_IS_ENABLED(DM_USB) */ 126 127 #if CONFIG_IS_ENABLED(DM_USB) 128 static int ehci_pci_probe(struct udevice *dev) 129 { 130 struct ehci_hccr *hccr; 131 struct ehci_hcor *hcor; 132 int ret; 133 134 ret = ehci_pci_init(dev, &hccr, &hcor); 135 if (ret) 136 return ret; 137 138 return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); 139 } 140 141 static int ehci_pci_remove(struct udevice *dev) 142 { 143 struct ehci_pci_priv *priv = dev_get_priv(dev); 144 int ret; 145 146 ret = ehci_deregister(dev); 147 if (ret) 148 return ret; 149 150 return ehci_shutdown_phy(dev, &priv->phy); 151 } 152 153 static const struct udevice_id ehci_pci_ids[] = { 154 { .compatible = "ehci-pci" }, 155 { } 156 }; 157 158 U_BOOT_DRIVER(ehci_pci) = { 159 .name = "ehci_pci", 160 .id = UCLASS_USB, 161 .probe = ehci_pci_probe, 162 .remove = ehci_pci_remove, 163 .of_match = ehci_pci_ids, 164 .ops = &ehci_usb_ops, 165 .platdata_auto_alloc_size = sizeof(struct usb_platdata), 166 .priv_auto_alloc_size = sizeof(struct ehci_pci_priv), 167 .flags = DM_FLAG_ALLOC_PRIV_DMA, 168 }; 169 170 static struct pci_device_id ehci_pci_supported[] = { 171 { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0) }, 172 {}, 173 }; 174 175 U_BOOT_PCI_DEVICE(ehci_pci, ehci_pci_supported); 176 177 #endif /* CONFIG_IS_ENABLED(DM_USB) */ 178