123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /*
- * am35x.c - TI's AM35x platform specific usb wrapper functions.
- *
- * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
- *
- * Based on drivers/usb/musb/da8xx.c
- *
- * Copyright (c) 2010 Texas Instruments Incorporated
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include "am35x.h"
- /* MUSB platform configuration */
- struct musb_config musb_cfg = {
- .regs = (struct musb_regs *)AM35X_USB_OTG_CORE_BASE,
- .timeout = AM35X_USB_OTG_TIMEOUT,
- .musb_speed = 0,
- };
- /*
- * Enable the USB phy
- */
- static u8 phy_on(void)
- {
- u32 devconf2;
- u32 timeout;
- devconf2 = readl(&am35x_scm_general_regs->devconf2);
- devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN |
- DEVCONF2_OTGMODE | DEVCONF2_REFFREQ |
- DEVCONF2_PHY_GPIOMODE);
- devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON |
- DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL;
- writel(devconf2, &am35x_scm_general_regs->devconf2);
- /* wait until the USB phy is turned on */
- timeout = musb_cfg.timeout;
- while (timeout--)
- if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD)
- return 1;
- /* USB phy was not turned on */
- return 0;
- }
- /*
- * Disable the USB phy
- */
- static void phy_off(void)
- {
- u32 devconf2;
- /*
- * Power down the on-chip PHY.
- */
- devconf2 = readl(&am35x_scm_general_regs->devconf2);
- devconf2 &= ~DEVCONF2_PHY_PLLON;
- devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN;
- writel(devconf2, &am35x_scm_general_regs->devconf2);
- }
- /*
- * This function performs platform specific initialization for usb0.
- */
- int musb_platform_init(void)
- {
- u32 revision;
- u32 sw_reset;
- /* global usb reset */
- sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset);
- sw_reset |= (1 << 0);
- writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
- sw_reset &= ~(1 << 0);
- writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
- /* reset the controller */
- writel(0x1, &am35x_usb_regs->control);
- udelay(5000);
- /* start the on-chip usb phy and its pll */
- if (phy_on() == 0)
- return -1;
- /* Returns zero if e.g. not clocked */
- revision = readl(&am35x_usb_regs->revision);
- if (revision == 0)
- return -1;
- return 0;
- }
- /*
- * This function performs platform specific deinitialization for usb0.
- */
- void musb_platform_deinit(void)
- {
- /* Turn off the phy */
- phy_off();
- }
- /*
- * This function reads data from endpoint fifo for AM35x
- * which supports only 32bit read operation.
- *
- * ep - endpoint number
- * length - number of bytes to read from FIFO
- * fifo_data - pointer to data buffer into which data is read
- */
- __attribute__((weak))
- void read_fifo(u8 ep, u32 length, void *fifo_data)
- {
- u8 *data = (u8 *)fifo_data;
- u32 val;
- int i;
- /* select the endpoint index */
- writeb(ep, &musbr->index);
- if (length > 4) {
- for (i = 0; i < (length >> 2); i++) {
- val = readl(&musbr->fifox[ep]);
- memcpy(data, &val, 4);
- data += 4;
- }
- length %= 4;
- }
- if (length > 0) {
- val = readl(&musbr->fifox[ep]);
- memcpy(data, &val, length);
- }
- }
|