uboot/drivers/usb/host/ehci-atmel.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2012
   3 * Atmel Semiconductor <www.atmel.com>
   4 * Written-by: Bo Shen <voice.shen@atmel.com>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <clk.h>
  11#include <dm.h>
  12#include <usb.h>
  13#include <asm/io.h>
  14#include <asm/arch/clk.h>
  15
  16#include "ehci.h"
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20#ifndef CONFIG_DM_USB
  21
  22int ehci_hcd_init(int index, enum usb_init_type init,
  23                struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  24{
  25        /* Enable UTMI PLL */
  26        if (at91_upll_clk_enable())
  27                return -1;
  28
  29        /* Enable USB Host clock */
  30        at91_periph_clk_enable(ATMEL_ID_UHPHS);
  31
  32        *hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
  33        *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
  34                        HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
  35
  36        return 0;
  37}
  38
  39int ehci_hcd_stop(int index)
  40{
  41        /* Disable USB Host Clock */
  42        at91_periph_clk_disable(ATMEL_ID_UHPHS);
  43
  44        /* Disable UTMI PLL */
  45        if (at91_upll_clk_disable())
  46                return -1;
  47
  48        return 0;
  49}
  50
  51#else
  52
  53struct ehci_atmel_priv {
  54        struct ehci_ctrl ehci;
  55};
  56
  57static int ehci_atmel_enable_clk(struct udevice *dev)
  58{
  59        struct clk clk;
  60        int ret;
  61
  62        ret = clk_get_by_index(dev, 0, &clk);
  63        if (ret)
  64                return ret;
  65
  66        ret = clk_enable(&clk);
  67        if (ret)
  68                return ret;
  69
  70        ret = clk_get_by_index(dev, 1, &clk);
  71        if (ret)
  72                return -EINVAL;
  73
  74        ret = clk_enable(&clk);
  75        if (ret)
  76                return ret;
  77
  78        clk_free(&clk);
  79
  80        return 0;
  81}
  82
  83static int ehci_atmel_probe(struct udevice *dev)
  84{
  85        struct ehci_hccr *hccr;
  86        struct ehci_hcor *hcor;
  87        fdt_addr_t hcd_base;
  88        int ret;
  89
  90        ret = ehci_atmel_enable_clk(dev);
  91        if (ret) {
  92                debug("Failed to enable USB Host clock\n");
  93                return ret;
  94        }
  95
  96        /*
  97         * Get the base address for EHCI controller from the device node
  98         */
  99        hcd_base = dev_get_addr(dev);
 100        if (hcd_base == FDT_ADDR_T_NONE) {
 101                debug("Can't get the EHCI register base address\n");
 102                return -ENXIO;
 103        }
 104
 105        hccr = (struct ehci_hccr *)hcd_base;
 106        hcor = (struct ehci_hcor *)
 107                ((u32)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 108
 109        debug("echi-atmel: init hccr %x and hcor %x hc_length %d\n",
 110              (u32)hccr, (u32)hcor,
 111              (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 112
 113        return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
 114}
 115
 116static const struct udevice_id ehci_usb_ids[] = {
 117        { .compatible = "atmel,at91sam9g45-ehci", },
 118        { }
 119};
 120
 121U_BOOT_DRIVER(ehci_atmel) = {
 122        .name           = "ehci_atmel",
 123        .id             = UCLASS_USB,
 124        .of_match       = ehci_usb_ids,
 125        .probe          = ehci_atmel_probe,
 126        .remove         = ehci_deregister,
 127        .ops            = &ehci_usb_ops,
 128        .platdata_auto_alloc_size = sizeof(struct usb_platdata),
 129        .priv_auto_alloc_size = sizeof(struct ehci_atmel_priv),
 130        .flags          = DM_FLAG_ALLOC_PRIV_DMA,
 131};
 132
 133#endif
 134