xref: /openbmc/u-boot/drivers/usb/host/ehci-pci.c (revision fea7f3aa)
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 
14 #include "ehci.h"
15 
16 /* Information about a USB port */
17 struct ehci_pci_priv {
18 	struct ehci_ctrl ehci;
19 };
20 
21 static void ehci_pci_common_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr,
22 				 struct ehci_hcor **ret_hcor)
23 {
24 	struct ehci_hccr *hccr;
25 	struct ehci_hcor *hcor;
26 	uint32_t cmd;
27 
28 	hccr = (struct ehci_hccr *)pci_map_bar(pdev,
29 			PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
30 	hcor = (struct ehci_hcor *)((uint32_t) hccr +
31 			HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
32 
33 	debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
34 	      (uint32_t)hccr, (uint32_t)hcor,
35 	      (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
36 
37 	*ret_hccr = hccr;
38 	*ret_hcor = hcor;
39 
40 	/* enable busmaster */
41 	pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
42 	cmd |= PCI_COMMAND_MASTER;
43 	pci_write_config_dword(pdev, PCI_COMMAND, cmd);
44 }
45 
46 #ifndef CONFIG_DM_USB
47 
48 #ifdef CONFIG_PCI_EHCI_DEVICE
49 static struct pci_device_id ehci_pci_ids[] = {
50 	/* Please add supported PCI EHCI controller ids here */
51 	{0x1033, 0x00E0},	/* NEC */
52 	{0x10B9, 0x5239},	/* ULI1575 PCI EHCI module ids */
53 	{0x12D8, 0x400F},	/* Pericom */
54 	{0, 0}
55 };
56 #endif
57 
58 /*
59  * Create the appropriate control structures to manage
60  * a new EHCI host controller.
61  */
62 int ehci_hcd_init(int index, enum usb_init_type init,
63 		struct ehci_hccr **ret_hccr, struct ehci_hcor **ret_hcor)
64 {
65 	pci_dev_t pdev;
66 
67 #ifdef CONFIG_PCI_EHCI_DEVICE
68 	pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
69 #else
70 	pdev = pci_find_class(PCI_CLASS_SERIAL_USB_EHCI, index);
71 #endif
72 	if (pdev < 0) {
73 		printf("EHCI host controller not found\n");
74 		return -1;
75 	}
76 	ehci_pci_common_init(pdev, ret_hccr, ret_hcor);
77 
78 	return 0;
79 }
80 
81 /*
82  * Destroy the appropriate control structures corresponding
83  * the the EHCI host controller.
84  */
85 int ehci_hcd_stop(int index)
86 {
87 	return 0;
88 }
89 #endif /* nCONFIG_DM_USB */
90 
91 #ifdef CONFIG_DM_USB
92 static int ehci_pci_probe(struct udevice *dev)
93 {
94 	struct ehci_hccr *hccr;
95 	struct ehci_hcor *hcor;
96 
97 	ehci_pci_common_init(pci_get_bdf(dev), &hccr, &hcor);
98 
99 	return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
100 }
101 
102 static int ehci_pci_remove(struct udevice *dev)
103 {
104 	int ret;
105 
106 	ret = ehci_deregister(dev);
107 	if (ret)
108 		return ret;
109 
110 	return 0;
111 }
112 
113 U_BOOT_DRIVER(ehci_pci) = {
114 	.name	= "ehci_pci",
115 	.id	= UCLASS_USB,
116 	.probe = ehci_pci_probe,
117 	.remove = ehci_pci_remove,
118 	.ops	= &ehci_usb_ops,
119 	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
120 	.priv_auto_alloc_size = sizeof(struct ehci_pci_priv),
121 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
122 };
123 
124 static struct pci_device_id ehci_pci_supported[] = {
125 	{ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0) },
126 	{},
127 };
128 
129 U_BOOT_PCI_DEVICE(ehci_pci, ehci_pci_supported);
130 
131 #endif /* CONFIG_DM_USB */
132