]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/usb/host/xhci-pci.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / usb / host / xhci-pci.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0
316328f5
SG
2/*
3 * Copyright (c) 2015, Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
5 * All rights reserved.
316328f5
SG
6 */
7
d678a59d 8#include <common.h>
555a3472 9#include <dm.h>
70a98caf 10#include <dm/device_compat.h>
691d719d 11#include <init.h>
f7ae49fc 12#include <log.h>
316328f5 13#include <pci.h>
70a98caf 14#include <reset.h>
316328f5 15#include <usb.h>
1708a123 16#include <usb/xhci.h>
316328f5 17
70a98caf
SH
18struct xhci_pci_plat {
19 struct reset_ctl reset;
20};
21
5a5024fe
T
22static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
23 struct xhci_hcor **ret_hcor)
555a3472
SR
24{
25 struct xhci_hccr *hccr;
26 struct xhci_hcor *hcor;
27 u32 cmd;
28
29 hccr = (struct xhci_hccr *)dm_pci_map_bar(dev,
2635e3b5
AS
30 PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE,
31 PCI_REGION_MEM);
5a5024fe
T
32 if (!hccr) {
33 printf("xhci-pci init cannot map PCI mem bar\n");
34 return -EIO;
35 }
36
555a3472
SR
37 hcor = (struct xhci_hcor *)((uintptr_t) hccr +
38 HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
39
9fddf6c7
BM
40 debug("XHCI-PCI init hccr %p and hcor %p hc_length %d\n",
41 hccr, hcor, (u32)HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
555a3472
SR
42
43 *ret_hccr = hccr;
44 *ret_hcor = hcor;
45
46 /* enable busmaster */
47 dm_pci_read_config32(dev, PCI_COMMAND, &cmd);
48 cmd |= PCI_COMMAND_MASTER;
49 dm_pci_write_config32(dev, PCI_COMMAND, cmd);
5a5024fe 50 return 0;
555a3472
SR
51}
52
53static int xhci_pci_probe(struct udevice *dev)
54{
70a98caf 55 struct xhci_pci_plat *plat = dev_get_plat(dev);
555a3472
SR
56 struct xhci_hccr *hccr;
57 struct xhci_hcor *hcor;
5a5024fe 58 int ret;
555a3472 59
70a98caf
SH
60 ret = reset_get_by_index(dev, 0, &plat->reset);
61 if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
62 dev_err(dev, "failed to get reset\n");
63 return ret;
64 }
65
66 if (reset_valid(&plat->reset)) {
67 ret = reset_assert(&plat->reset);
68 if (ret)
69 goto err_reset;
70
71 ret = reset_deassert(&plat->reset);
72 if (ret)
73 goto err_reset;
74 }
75
5a5024fe
T
76 ret = xhci_pci_init(dev, &hccr, &hcor);
77 if (ret)
70a98caf
SH
78 goto err_reset;
79
80 ret = xhci_register(dev, hccr, hcor);
81 if (ret)
82 goto err_reset;
83
84 return 0;
85
86err_reset:
87 if (reset_valid(&plat->reset))
88 reset_free(&plat->reset);
89
90 return ret;
91}
92
93static int xhci_pci_remove(struct udevice *dev)
94{
95 struct xhci_pci_plat *plat = dev_get_plat(dev);
555a3472 96
70a98caf
SH
97 xhci_deregister(dev);
98 if (reset_valid(&plat->reset))
99 reset_free(&plat->reset);
100
101 return 0;
555a3472
SR
102}
103
555a3472
SR
104static const struct udevice_id xhci_pci_ids[] = {
105 { .compatible = "xhci-pci" },
106 { }
107};
108
109U_BOOT_DRIVER(xhci_pci) = {
110 .name = "xhci_pci",
111 .id = UCLASS_USB,
112 .probe = xhci_pci_probe,
70a98caf 113 .remove = xhci_pci_remove,
555a3472
SR
114 .of_match = xhci_pci_ids,
115 .ops = &xhci_usb_ops,
70a98caf 116 .plat_auto = sizeof(struct xhci_pci_plat),
41575d8e 117 .priv_auto = sizeof(struct xhci_ctrl),
e3bbc1f7 118 .flags = DM_FLAG_OS_PREPARE | DM_FLAG_ALLOC_PRIV_DMA,
555a3472
SR
119};
120
121static struct pci_device_id xhci_pci_supported[] = {
122 { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0) },
123 {},
124};
125
126U_BOOT_PCI_DEVICE(xhci_pci, xhci_pci_supported);