190fbb282SAlexey Brodkin /* 290fbb282SAlexey Brodkin * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com> 390fbb282SAlexey Brodkin * 490fbb282SAlexey Brodkin * SPDX-License-Identifier: GPL-2.0+ 590fbb282SAlexey Brodkin */ 690fbb282SAlexey Brodkin 790fbb282SAlexey Brodkin #include <common.h> 84feefdcfSMasahiro Yamada #include <clk.h> 9*8824cfc1SMasahiro Yamada #include <reset.h> 10643cacb6SMarek Vasut #include <asm/io.h> 1190fbb282SAlexey Brodkin #include <dm.h> 1290fbb282SAlexey Brodkin #include "ehci.h" 1390fbb282SAlexey Brodkin 1490fbb282SAlexey Brodkin /* 1590fbb282SAlexey Brodkin * Even though here we don't explicitly use "struct ehci_ctrl" 1690fbb282SAlexey Brodkin * ehci_register() expects it to be the first thing that resides in 1790fbb282SAlexey Brodkin * device's private data. 1890fbb282SAlexey Brodkin */ 1990fbb282SAlexey Brodkin struct generic_ehci { 2090fbb282SAlexey Brodkin struct ehci_ctrl ctrl; 2190fbb282SAlexey Brodkin }; 2290fbb282SAlexey Brodkin 2390fbb282SAlexey Brodkin static int ehci_usb_probe(struct udevice *dev) 2490fbb282SAlexey Brodkin { 25643cacb6SMarek Vasut struct ehci_hccr *hccr; 2690fbb282SAlexey Brodkin struct ehci_hcor *hcor; 274feefdcfSMasahiro Yamada int i; 284feefdcfSMasahiro Yamada 294feefdcfSMasahiro Yamada for (i = 0; ; i++) { 30135aa950SStephen Warren struct clk clk; 31135aa950SStephen Warren int ret; 324feefdcfSMasahiro Yamada 33135aa950SStephen Warren ret = clk_get_by_index(dev, i, &clk); 34135aa950SStephen Warren if (ret < 0) 354feefdcfSMasahiro Yamada break; 36135aa950SStephen Warren if (clk_enable(&clk)) 37135aa950SStephen Warren printf("failed to enable clock %d\n", i); 38135aa950SStephen Warren clk_free(&clk); 394feefdcfSMasahiro Yamada } 4090fbb282SAlexey Brodkin 41*8824cfc1SMasahiro Yamada for (i = 0; ; i++) { 42*8824cfc1SMasahiro Yamada struct reset_ctl reset; 43*8824cfc1SMasahiro Yamada int ret; 44*8824cfc1SMasahiro Yamada 45*8824cfc1SMasahiro Yamada ret = reset_get_by_index(dev, i, &reset); 46*8824cfc1SMasahiro Yamada if (ret < 0) 47*8824cfc1SMasahiro Yamada break; 48*8824cfc1SMasahiro Yamada if (reset_deassert(&reset)) 49*8824cfc1SMasahiro Yamada printf("failed to deassert reset %d\n", i); 50*8824cfc1SMasahiro Yamada reset_free(&reset); 51*8824cfc1SMasahiro Yamada } 52*8824cfc1SMasahiro Yamada 53643cacb6SMarek Vasut hccr = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE); 5490fbb282SAlexey Brodkin hcor = (struct ehci_hcor *)((uintptr_t)hccr + 5590fbb282SAlexey Brodkin HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 5690fbb282SAlexey Brodkin 5790fbb282SAlexey Brodkin return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); 5890fbb282SAlexey Brodkin } 5990fbb282SAlexey Brodkin 6090fbb282SAlexey Brodkin static const struct udevice_id ehci_usb_ids[] = { 6190fbb282SAlexey Brodkin { .compatible = "generic-ehci" }, 6290fbb282SAlexey Brodkin { } 6390fbb282SAlexey Brodkin }; 6490fbb282SAlexey Brodkin 6590fbb282SAlexey Brodkin U_BOOT_DRIVER(ehci_generic) = { 6690fbb282SAlexey Brodkin .name = "ehci_generic", 6790fbb282SAlexey Brodkin .id = UCLASS_USB, 6890fbb282SAlexey Brodkin .of_match = ehci_usb_ids, 6990fbb282SAlexey Brodkin .probe = ehci_usb_probe, 7040527342SMasahiro Yamada .remove = ehci_deregister, 7190fbb282SAlexey Brodkin .ops = &ehci_usb_ops, 7290fbb282SAlexey Brodkin .priv_auto_alloc_size = sizeof(struct generic_ehci), 7390fbb282SAlexey Brodkin .flags = DM_FLAG_ALLOC_PRIV_DMA, 7490fbb282SAlexey Brodkin }; 75