/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/mmio.h>
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <soc/gpio.h>
#include <soc/power.h>
#include <soc/sysreg.h>
#include <soc/usb.h>

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

void reset_usb_drd_dwc3(void)
{
	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) */

	write32(&dwc3->usb3pipectl,
		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 */

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

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

void setup_usb_drd_dwc3(void)
{
	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 */
	setbits32(&phy->linksystem, 0x1 << 27 | 0x20 << 1);

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

	write32(&phy->clkrst,
		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 */

	write32(&phy->param0,
		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 */

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

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

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

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

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

void setup_usb_drd_phy(void)
{
	printk(BIOS_DEBUG, "Powering up USB DRD PHY\n");
	setbits32(&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;

	setbits32(&exynos_sysreg->usb20_phy_cfg, USB20_PHY_CFG_EN);
	setbits32(&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 = read32(&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);
	write32(&exynos_usb_host_phy->usbphyctrl0, hostphy_ctrl0);
	udelay(10);
	clrbits32(&exynos_usb_host_phy->usbphyctrl0,
		  HOST_CTRL0_LINKSWRST |
		  HOST_CTRL0_UTMISWRST);
	udelay(20);

	/* EHCI Ctrl setting */
	setbits32(&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);

		clrbits32(&exynos_usb_host_phy->hsicphyctrl1,
			  HOST_CTRL0_SIDDQ |
			  HOST_CTRL0_FORCESLEEP |
			  HOST_CTRL0_FORCESUSPEND);
		setbits32(&exynos_usb_host_phy->hsicphyctrl1,
			  HOST_CTRL0_PHYSWRST);
		udelay(10);
		clrbits32(&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.
	 */
}
