/*
 * (C) Copyright 2010, Damien Dusha, <d.dusha@gmail.com>
 *
 * (C) Copyright 2009, Value Team S.p.A.
 * Francesco Rendine, <francesco.rendine@valueteam.com>
 *
 * (C) Copyright 2009 Freescale Semiconductor, Inc.
 *
 * (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
 *
 * Author: Tor Krill tor@excito.com
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <pci.h>
#include <usb.h>
#include <asm/io.h>
#include <usb/ehci-fsl.h>

#include "ehci.h"

static void fsl_setup_phy(volatile struct ehci_hcor *);
static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci);
static int reset_usb_controller(volatile struct usb_ehci *ehci);
static void usb_platform_dr_init(volatile struct usb_ehci *ehci);

/*
 * Initialize SOC FSL EHCI Controller
 *
 * This code is derived from EHCI FSL USB Linux driver for MPC5121
 *
 */
int ehci_hcd_init(int index, enum usb_init_type init,
		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	volatile struct usb_ehci *ehci;

	/* Hook the memory mapped registers for EHCI-Controller */
	ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB1_ADDR;
	*hccr = (struct ehci_hccr *)((uint32_t)&(ehci->caplength));
	*hcor = (struct ehci_hcor *)((uint32_t) *hccr +
				HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));

	/* configure interface for UTMI_WIDE */
	usb_platform_dr_init(ehci);

	/* Init Phy USB0 to UTMI+ */
	fsl_setup_phy(*hcor);

	/* Set to host mode */
	fsl_platform_set_host_mode(ehci);

	/*
	 * Setting the burst size seems to be required to prevent the
	 * USB from hanging when communicating with certain USB Mass
	 * storage devices. This was determined by analysing the
	 * EHCI registers under Linux vs U-Boot and burstsize was the
	 * major non-interrupt related difference between the two
	 * implementations.
	 *
	 * Some USB sticks behave better than others. In particular,
	 * the following USB stick is especially problematic:
	 * 0930:6545 Toshiba Corp
	 *
	 * The burstsize is set here to match the Linux implementation.
	 */
	out_be32(&ehci->burstsize, FSL_EHCI_TXPBURST(8) |
				   FSL_EHCI_RXPBURST(8));

	return 0;
}

/*
 * Destroy the appropriate control structures corresponding
 * the the EHCI host controller.
 */
int ehci_hcd_stop(int index)
{
	volatile struct usb_ehci *ehci;
	int exit_status = 0;

	/* Reset the USB controller */
	ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB1_ADDR;
	exit_status = reset_usb_controller(ehci);

	return exit_status;
}

static int reset_usb_controller(volatile struct usb_ehci *ehci)
{
	unsigned int i;

	/* Command a reset of the USB Controller */
	out_be32(&(ehci->usbcmd), EHCI_FSL_USBCMD_RST);

	/* Wait for the reset process to finish */
	for (i = 65535 ; i > 0 ; i--) {
		/*
		 * The host will set this bit to zero once the
		 * reset process is complete
		 */
		if ((in_be32(&(ehci->usbcmd)) & EHCI_FSL_USBCMD_RST) == 0)
			return 0;
	}

	/* Hub did not reset in time */
	return -1;
}

static void fsl_setup_phy(volatile struct ehci_hcor *hcor)
{
	uint32_t portsc;

	portsc  = ehci_readl(&hcor->or_portsc[0]);
	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);

	/* Enable the phy mode to UTMI Wide */
	portsc |= PORT_PTS_PTW;
	portsc |= PORT_PTS_UTMI;

	ehci_writel(&hcor->or_portsc[0], portsc);
}

static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci)
{
	uint32_t temp;

	temp  = in_le32(&ehci->usbmode);
	temp |= CM_HOST | ES_BE;
	out_le32(&ehci->usbmode, temp);
}

static void usb_platform_dr_init(volatile struct usb_ehci *ehci)
{
	/* Configure interface for UTMI_WIDE */
	out_be32(&ehci->isiphyctrl, PHYCTRL_PHYE | PHYCTRL_PXE);
	out_be32(&ehci->usbgenctrl, GC_PPP | GC_PFP );
}
