xref: /openbmc/u-boot/drivers/usb/host/ehci-generic.c (revision ad5b5801)
1 /*
2  * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <clk.h>
9 #include <asm/io.h>
10 #include <dm.h>
11 #include "ehci.h"
12 
13 /*
14  * Even though here we don't explicitly use "struct ehci_ctrl"
15  * ehci_register() expects it to be the first thing that resides in
16  * device's private data.
17  */
18 struct generic_ehci {
19 	struct ehci_ctrl ctrl;
20 };
21 
22 static int ehci_usb_probe(struct udevice *dev)
23 {
24 	struct ehci_hccr *hccr;
25 	struct ehci_hcor *hcor;
26 	int i;
27 
28 	for (i = 0; ; i++) {
29 		struct udevice *clk_dev;
30 		int clk_id;
31 
32 		clk_id = clk_get_by_index(dev, i, &clk_dev);
33 		if (clk_id < 0)
34 			break;
35 		if (clk_enable(clk_dev, clk_id))
36 			printf("failed to enable clock (dev=%s, id=%d)\n",
37 			       clk_dev->name, clk_id);
38 	}
39 
40 	hccr = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
41 	hcor = (struct ehci_hcor *)((uintptr_t)hccr +
42 				    HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
43 
44 	return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
45 }
46 
47 static int ehci_usb_remove(struct udevice *dev)
48 {
49 	return ehci_deregister(dev);
50 }
51 
52 static const struct udevice_id ehci_usb_ids[] = {
53 	{ .compatible = "generic-ehci" },
54 	{ }
55 };
56 
57 U_BOOT_DRIVER(ehci_generic) = {
58 	.name	= "ehci_generic",
59 	.id	= UCLASS_USB,
60 	.of_match = ehci_usb_ids,
61 	.probe = ehci_usb_probe,
62 	.remove = ehci_usb_remove,
63 	.ops	= &ehci_usb_ops,
64 	.priv_auto_alloc_size = sizeof(struct generic_ehci),
65 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
66 };
67