/*
 * 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
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#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);
	}
}
