/*
 * (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-ci.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), CMD_RESET);

	/* 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)) & CMD_RESET) == 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 );
}
