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