1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2014, Xilinx, Inc 4 * 5 * USB Low level initialization(Specific to zynq) 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <usb.h> 11 #include <asm/arch/hardware.h> 12 #include <asm/arch/sys_proto.h> 13 #include <asm/io.h> 14 #include <usb/ehci-ci.h> 15 #include <usb/ulpi.h> 16 17 #include "ehci.h" 18 19 struct zynq_ehci_priv { 20 struct ehci_ctrl ehcictrl; 21 struct usb_ehci *ehci; 22 }; 23 24 static int ehci_zynq_ofdata_to_platdata(struct udevice *dev) 25 { 26 struct zynq_ehci_priv *priv = dev_get_priv(dev); 27 28 priv->ehci = (struct usb_ehci *)devfdt_get_addr_ptr(dev); 29 if (!priv->ehci) 30 return -EINVAL; 31 32 return 0; 33 } 34 35 static int ehci_zynq_probe(struct udevice *dev) 36 { 37 struct usb_platdata *plat = dev_get_platdata(dev); 38 struct zynq_ehci_priv *priv = dev_get_priv(dev); 39 struct ehci_hccr *hccr; 40 struct ehci_hcor *hcor; 41 struct ulpi_viewport ulpi_vp; 42 /* Used for writing the ULPI data address */ 43 struct ulpi_regs *ulpi = (struct ulpi_regs *)0; 44 int ret; 45 46 hccr = (struct ehci_hccr *)((uint32_t)&priv->ehci->caplength); 47 hcor = (struct ehci_hcor *)((uint32_t) hccr + 48 HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 49 50 ulpi_vp.viewport_addr = (u32)&priv->ehci->ulpi_viewpoint; 51 ulpi_vp.port_num = 0; 52 53 ret = ulpi_init(&ulpi_vp); 54 if (ret) { 55 puts("zynq ULPI viewport init failed\n"); 56 return -1; 57 } 58 59 /* ULPI set flags */ 60 ulpi_write(&ulpi_vp, &ulpi->otg_ctrl, 61 ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN | 62 ULPI_OTG_EXTVBUSIND); 63 ulpi_write(&ulpi_vp, &ulpi->function_ctrl, 64 ULPI_FC_FULL_SPEED | ULPI_FC_OPMODE_NORMAL | 65 ULPI_FC_SUSPENDM); 66 ulpi_write(&ulpi_vp, &ulpi->iface_ctrl, 0); 67 68 /* Set VBus */ 69 ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, 70 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); 71 72 return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type); 73 } 74 75 static const struct udevice_id ehci_zynq_ids[] = { 76 { .compatible = "xlnx,zynq-usb-2.20a" }, 77 { } 78 }; 79 80 U_BOOT_DRIVER(ehci_zynq) = { 81 .name = "ehci_zynq", 82 .id = UCLASS_USB, 83 .of_match = ehci_zynq_ids, 84 .ofdata_to_platdata = ehci_zynq_ofdata_to_platdata, 85 .probe = ehci_zynq_probe, 86 .remove = ehci_deregister, 87 .ops = &ehci_usb_ops, 88 .platdata_auto_alloc_size = sizeof(struct usb_platdata), 89 .priv_auto_alloc_size = sizeof(struct zynq_ehci_priv), 90 .flags = DM_FLAG_ALLOC_PRIV_DMA, 91 }; 92