/*
 * 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_drd_dwc3()
{
	printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD\n");
	reset_dwc3(exynos_usb_drd_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_drd_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_drd_dwc3()
{
	setup_dwc3(exynos_usb_drd_dwc3);
	printk(BIOS_DEBUG, "DWC3 setup for USB DRD 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_drd_phy()
{
	printk(BIOS_DEBUG, "Powering up USB DRD PHY\n");
	setbits_le32(&exynos_power->usb_drd_phy_ctrl, POWER_USB_PHY_CTRL_EN);
	setup_drd_phy(exynos_usb_drd_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.
	 */
}
