/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2012 Samsung Electronics
 * Copyright 2013 Google Inc.
 *
 * 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; version 2 of the License.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <delay.h>
#include <arch/io.h>
#include <console/console.h>
#include <device/device.h>
#include "gpio.h"
#include "power.h"
#include "sysreg.h"
#include "usb.h"

static void reset_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
{
	setbits_le32(&dwc3->ctl, 0x1 << 11);		/* core soft reset */
	setbits_le32(&dwc3->usb3pipectl, 0x1 << 31);	/* PHY soft reset */
	setbits_le32(&dwc3->usb2phycfg, 0x1 << 31);	/* PHY soft reset */
}

void reset_usb_drd0_dwc3()
{
	printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD0\n");
	reset_dwc3(exynos_usb_drd0_dwc3);
}

void reset_usb_drd1_dwc3()
{
	printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD1\n");
	reset_dwc3(exynos_usb_drd1_dwc3);
}

static void setup_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
{
	if (!(dwc3->ctl & 0x1 << 11) ||
	    !(dwc3->usb3pipectl & 0x1 << 31) ||
	    !(dwc3->usb2phycfg & 0x1 << 31)) {
		printk(BIOS_ERR, "DWC3 at %p not in reset (you need to call "
		       "reset_usb_drdX_dwc3() first)!\n", dwc3);
	}

	/* Set relevant registers to default values (clearing all reset bits) */

	writel(0x1 << 24 |	/* activate PHY low power states */
	       0x4 << 19 |	/* low power delay value */
	       0x1 << 18 |	/* activate PHY low power delay */
	       0x1 << 17 |	/* enable SuperSpeed PHY suspend */
	       0x1 << 1 |	/* default Tx deemphasis value */
	       0, &dwc3->usb3pipectl);

	/* Configure PHY clock turnaround for 8-bit UTMI+, disable suspend */
	writel(0x9 << 10 |	/* PHY clock turnaround for 8-bit UTMI+ */
	       0x1 << 8 |	/* enable PHY sleep in L1 */
	       0x1 << 6 |	/* enable PHY suspend */
	       0, &dwc3->usb2phycfg);

	writel(0x5dc << 19 |	/* suspend clock scale for 24MHz */
	       0x1 << 16 |	/* retry SS three times (bugfix from U-Boot) */
	       0x1 << 12 |	/* port capability HOST */
	       0, &dwc3->ctl);
}

void setup_usb_drd0_dwc3()
{
	setup_dwc3(exynos_usb_drd0_dwc3);
	printk(BIOS_DEBUG, "DWC3 setup for USB DRD0 finished\n");
}

void setup_usb_drd1_dwc3()
{
	setup_dwc3(exynos_usb_drd1_dwc3);
	printk(BIOS_DEBUG, "DWC3 setup for USB DRD1 finished\n");
}

static void setup_drd_phy(struct exynos5_usb_drd_phy *phy)
{
	/* Set all PHY registers to default values */

	/* XHCI Version 1.0, Frame Length adjustment 30 MHz */
	setbits_le32(&phy->linksystem, 0x1 << 27 | 0x20 << 1);

	/* Disable OTG, ID0 and DRVVBUS, do not force sleep/suspend */
	writel(1 << 6, &phy->utmi);

	writel(0x88 << 23 |	/* spread spectrum refclk selector */
	       0x1 << 20 |	/* enable spread spectrum */
	       0x1 << 19 |	/* enable prescaler refclk */
	       0x68 << 11 |	/* multiplier for 24MHz refclk */
	       0x5 << 5 |	/* select 24MHz refclk (weird, from U-Boot) */
	       0x1 << 4 |	/* power supply in normal operating mode */
	       0x3 << 2 |	/* use external refclk (undocumented on 5420?)*/
	       0x1 << 1 |	/* force port reset */
	       0x1 << 0 |	/* normal operating mode */
	       0, &phy->clkrst);

	writel(0x9 << 26 |	/* LOS level */
	       0x3 << 22 |	/* TX VREF tune */
	       0x1 << 20 |	/* TX rise tune */
	       0x1 << 18 |	/* TX res tune */
	       0x3 << 13 |	/* TX HS X Vtune */
	       0x3 << 9 |	/* TX FS/LS tune */
	       0x3 << 6 |	/* SQRX tune */
	       0x4 << 3 |	/* OTG tune */
	       0x4 << 0 |	/* comp disc tune */
	       0, &phy->param0);

	writel(0x7f << 19 |	/* reserved */
	       0x7f << 12 |	/* Tx launch amplitude */
	       0x20 << 6 |	/* Tx deemphasis 6dB */
	       0x1c << 0 |	/* Tx deemphasis 3.5dB (value from U-Boot) */
	       0, &phy->param1);

	/* disable all test features */
	writel(0, &phy->test);

	/* UTMI clock select? ("must be 0x1") */
	writel(0x1 << 2, &phy->utmiclksel);

	/* Samsung magic, undocumented (from U-Boot) */
	writel(0x0, &phy->resume);

	udelay(10);
	clrbits_le32(&phy->clkrst, 0x1 << 1);  /* deassert port reset */
}

void setup_usb_drd0_phy()
{
	printk(BIOS_DEBUG, "Powering up USB DRD0 PHY\n");
	setbits_le32(&exynos_power->usb_drd0_phy_ctrl, POWER_USB_PHY_CTRL_EN);
	setup_drd_phy(exynos_usb_drd0_phy);
}

void setup_usb_drd1_phy()
{
	printk(BIOS_DEBUG, "Powering up USB DRD1 PHY\n");
	setbits_le32(&exynos_power->usb_drd1_phy_ctrl, POWER_USB_PHY_CTRL_EN);
	setup_drd_phy(exynos_usb_drd1_phy);
}

void setup_usb_host_phy(int hsic_gpio)
{
	unsigned int hostphy_ctrl0;

	setbits_le32(&exynos_sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN);
	setbits_le32(&exynos_power->usb_host_phy_ctrl, POWER_USB_PHY_CTRL_EN);

	printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n",
			hsic_gpio ? "with" : "without");

	hostphy_ctrl0 = readl(&exynos_usb_host_phy->usbphyctrl0);
	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK |
			   HOST_CTRL0_COMMONON_N |
			   /* HOST Phy setting */
			   HOST_CTRL0_PHYSWRST |
			   HOST_CTRL0_PHYSWRSTALL |
			   HOST_CTRL0_SIDDQ |
			   HOST_CTRL0_FORCESUSPEND |
			   HOST_CTRL0_FORCESLEEP);
	hostphy_ctrl0 |= (/* Setting up the ref freq */
			  CLK_24MHZ << 16 |
			  /* HOST Phy setting */
			  HOST_CTRL0_LINKSWRST |
			  HOST_CTRL0_UTMISWRST);
	writel(hostphy_ctrl0, &exynos_usb_host_phy->usbphyctrl0);
	udelay(10);
	clrbits_le32(&exynos_usb_host_phy->usbphyctrl0,
		     HOST_CTRL0_LINKSWRST |
		     HOST_CTRL0_UTMISWRST);
	udelay(20);

	/* EHCI Ctrl setting */
	setbits_le32(&exynos_usb_host_phy->ehcictrl,
		     EHCICTRL_ENAINCRXALIGN |
		     EHCICTRL_ENAINCR4 |
		     EHCICTRL_ENAINCR8 |
		     EHCICTRL_ENAINCR16);

	/* HSIC USB Hub initialization. */
	if (hsic_gpio) {
		gpio_direction_output(hsic_gpio, 0);
		udelay(100);
		gpio_direction_output(hsic_gpio, 1);
		udelay(5000);

		clrbits_le32(&exynos_usb_host_phy->hsicphyctrl1,
			     HOST_CTRL0_SIDDQ |
			     HOST_CTRL0_FORCESLEEP |
			     HOST_CTRL0_FORCESUSPEND);
		setbits_le32(&exynos_usb_host_phy->hsicphyctrl1,
			     HOST_CTRL0_PHYSWRST);
		udelay(10);
		clrbits_le32(&exynos_usb_host_phy->hsicphyctrl1,
			     HOST_CTRL0_PHYSWRST);
	}

	/* At this point we need to wait for 50ms before talking to
	 * the USB controller (PHY clock and power setup time)
	 * By the time we are actually in the payload, these 50ms
	 * will have passed.
	 */
}
