uboot/drivers/usb/host/ehci-zynq.c
<<
>>
Prefs
   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
  20struct zynq_ehci_priv {
  21        struct ehci_ctrl ehcictrl;
  22        struct usb_ehci *ehci;
  23};
  24
  25static 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
  36static 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
  76static 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
  87static const struct udevice_id ehci_zynq_ids[] = {
  88        { .compatible = "xlnx,zynq-usb-2.20a" },
  89        { }
  90};
  91
  92U_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