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