uboot/drivers/usb/musb/am35x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * am35x.c - TI's AM35x platform specific usb wrapper functions.
   4 *
   5 * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
   6 *
   7 * Based on drivers/usb/musb/da8xx.c
   8 *
   9 * Copyright (c) 2010 Texas Instruments Incorporated
  10 */
  11
  12#include <common.h>
  13#include <linux/delay.h>
  14
  15#include "am35x.h"
  16
  17/* MUSB platform configuration */
  18struct musb_config musb_cfg = {
  19        .regs           = (struct musb_regs *)AM35X_USB_OTG_CORE_BASE,
  20        .timeout        = AM35X_USB_OTG_TIMEOUT,
  21        .musb_speed     = 0,
  22};
  23
  24/*
  25 * Enable the USB phy
  26 */
  27static u8 phy_on(void)
  28{
  29        u32 devconf2;
  30        u32 timeout;
  31
  32        devconf2 = readl(&am35x_scm_general_regs->devconf2);
  33
  34        devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN |
  35                      DEVCONF2_OTGMODE | DEVCONF2_REFFREQ |
  36                      DEVCONF2_PHY_GPIOMODE);
  37        devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON |
  38                    DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL;
  39
  40        writel(devconf2, &am35x_scm_general_regs->devconf2);
  41
  42        /* wait until the USB phy is turned on */
  43        timeout = musb_cfg.timeout;
  44        while (timeout--)
  45                if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD)
  46                        return 1;
  47
  48        /* USB phy was not turned on */
  49        return 0;
  50}
  51
  52/*
  53 * Disable the USB phy
  54 */
  55static void phy_off(void)
  56{
  57        u32 devconf2;
  58
  59        /*
  60         * Power down the on-chip PHY.
  61         */
  62        devconf2 = readl(&am35x_scm_general_regs->devconf2);
  63
  64        devconf2 &= ~DEVCONF2_PHY_PLLON;
  65        devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN;
  66        writel(devconf2, &am35x_scm_general_regs->devconf2);
  67}
  68
  69/*
  70 * This function performs platform specific initialization for usb0.
  71 */
  72int musb_platform_init(void)
  73{
  74        u32 revision;
  75        u32 sw_reset;
  76
  77        /* global usb reset */
  78        sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset);
  79        sw_reset |= (1 << 0);
  80        writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
  81        sw_reset &= ~(1 << 0);
  82        writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
  83
  84        /* reset the controller */
  85        writel(0x1, &am35x_usb_regs->control);
  86        udelay(5000);
  87
  88        /* start the on-chip usb phy and its pll */
  89        if (phy_on() == 0)
  90                return -1;
  91
  92        /* Returns zero if e.g. not clocked */
  93        revision = readl(&am35x_usb_regs->revision);
  94        if (revision == 0)
  95                return -1;
  96
  97        return 0;
  98}
  99
 100/*
 101 * This function performs platform specific deinitialization for usb0.
 102 */
 103void musb_platform_deinit(void)
 104{
 105        /* Turn off the phy */
 106        phy_off();
 107}
 108
 109/*
 110 * This function reads data from endpoint fifo for AM35x
 111 * which supports only 32bit read operation.
 112 *
 113 * ep           - endpoint number
 114 * length       - number of bytes to read from FIFO
 115 * fifo_data    - pointer to data buffer into which data is read
 116 */
 117__attribute__((weak))
 118void read_fifo(u8 ep, u32 length, void *fifo_data)
 119{
 120        u8  *data = (u8 *)fifo_data;
 121        u32 val;
 122        int i;
 123
 124        /* select the endpoint index */
 125        writeb(ep, &musbr->index);
 126
 127        if (length > 4) {
 128                for (i = 0; i < (length >> 2); i++) {
 129                        val = readl(&musbr->fifox[ep]);
 130                        memcpy(data, &val, 4);
 131                        data += 4;
 132                }
 133                length %= 4;
 134        }
 135        if (length > 0) {
 136                val = readl(&musbr->fifox[ep]);
 137                memcpy(data, &val, length);
 138        }
 139}
 140