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