/*
 * Freescale i.MX28 USB Host driver
 *
 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
 * on behalf of DENX Software Engineering GmbH
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <errno.h>

#include "ehci.h"

/* This DIGCTL register ungates clock to USB */
#define	HW_DIGCTL_CTRL			0x8001c000
#define	HW_DIGCTL_CTRL_USB0_CLKGATE	(1 << 2)
#define	HW_DIGCTL_CTRL_USB1_CLKGATE	(1 << 16)

struct ehci_mxs_port {
	uint32_t		usb_regs;
	struct mxs_usbphy_regs	*phy_regs;

	struct mxs_register_32	*pll;
	uint32_t		pll_en_bits;
	uint32_t		pll_dis_bits;
	uint32_t		gate_bits;
};

static const struct ehci_mxs_port mxs_port[] = {
#ifdef CONFIG_EHCI_MXS_PORT0
	{
		MXS_USBCTRL0_BASE,
		(struct mxs_usbphy_regs *)MXS_USBPHY0_BASE,
		(struct mxs_register_32 *)(MXS_CLKCTRL_BASE +
			offsetof(struct mxs_clkctrl_regs,
			hw_clkctrl_pll0ctrl0_reg)),
		CLKCTRL_PLL0CTRL0_EN_USB_CLKS | CLKCTRL_PLL0CTRL0_POWER,
		CLKCTRL_PLL0CTRL0_EN_USB_CLKS,
		HW_DIGCTL_CTRL_USB0_CLKGATE,
	},
#endif
#ifdef CONFIG_EHCI_MXS_PORT1
	{
		MXS_USBCTRL1_BASE,
		(struct mxs_usbphy_regs *)MXS_USBPHY1_BASE,
		(struct mxs_register_32 *)(MXS_CLKCTRL_BASE +
			offsetof(struct mxs_clkctrl_regs,
			hw_clkctrl_pll1ctrl0_reg)),
		CLKCTRL_PLL1CTRL0_EN_USB_CLKS | CLKCTRL_PLL1CTRL0_POWER,
		CLKCTRL_PLL1CTRL0_EN_USB_CLKS,
		HW_DIGCTL_CTRL_USB1_CLKGATE,
	},
#endif
};

static int ehci_mxs_toggle_clock(const struct ehci_mxs_port *port, int enable)
{
	struct mxs_register_32 *digctl_ctrl =
		(struct mxs_register_32 *)HW_DIGCTL_CTRL;
	int pll_offset, dig_offset;

	if (enable) {
		pll_offset = offsetof(struct mxs_register_32, reg_set);
		dig_offset = offsetof(struct mxs_register_32, reg_clr);
		writel(port->gate_bits, (u32)&digctl_ctrl->reg + dig_offset);
		writel(port->pll_en_bits, (u32)port->pll + pll_offset);
	} else {
		pll_offset = offsetof(struct mxs_register_32, reg_clr);
		dig_offset = offsetof(struct mxs_register_32, reg_set);
		writel(port->pll_dis_bits, (u32)port->pll + pll_offset);
		writel(port->gate_bits, (u32)&digctl_ctrl->reg + dig_offset);
	}

	return 0;
}

int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{

	int ret;
	uint32_t usb_base, cap_base;
	const struct ehci_mxs_port *port;

	if ((index < 0) || (index >= ARRAY_SIZE(mxs_port))) {
		printf("Invalid port index (index = %d)!\n", index);
		return -EINVAL;
	}

	port = &mxs_port[index];

	/* Reset the PHY block */
	writel(USBPHY_CTRL_SFTRST, &port->phy_regs->hw_usbphy_ctrl_set);
	udelay(10);
	writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE,
		&port->phy_regs->hw_usbphy_ctrl_clr);

	/* Enable USB clock */
	ret = ehci_mxs_toggle_clock(port, 1);
	if (ret)
		return ret;

	/* Start USB PHY */
	writel(0, &port->phy_regs->hw_usbphy_pwd);

	/* Enable UTMI+ Level 2 and Level 3 compatibility */
	writel(USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2 | 1,
		&port->phy_regs->hw_usbphy_ctrl_set);

	usb_base = port->usb_regs + 0x100;
	*hccr = (struct ehci_hccr *)usb_base;

	cap_base = ehci_readl(&(*hccr)->cr_capbase);
	*hcor = (struct ehci_hcor *)(usb_base + HC_LENGTH(cap_base));

	return 0;
}

int ehci_hcd_stop(int index)
{
	int ret;
	uint32_t usb_base, cap_base, tmp;
	struct ehci_hccr *hccr;
	struct ehci_hcor *hcor;
	const struct ehci_mxs_port *port;

	if ((index < 0) || (index >= ARRAY_SIZE(mxs_port))) {
		printf("Invalid port index (index = %d)!\n", index);
		return -EINVAL;
	}

	port = &mxs_port[index];

	/* Stop the USB port */
	usb_base = port->usb_regs + 0x100;
	hccr = (struct ehci_hccr *)usb_base;
	cap_base = ehci_readl(&hccr->cr_capbase);
	hcor = (struct ehci_hcor *)(usb_base + HC_LENGTH(cap_base));

	tmp = ehci_readl(&hcor->or_usbcmd);
	tmp &= ~CMD_RUN;
	ehci_writel(tmp, &hcor->or_usbcmd);

	/* Disable the PHY */
	tmp = USBPHY_PWD_RXPWDRX | USBPHY_PWD_RXPWDDIFF |
		USBPHY_PWD_RXPWD1PT1 | USBPHY_PWD_RXPWDENV |
		USBPHY_PWD_TXPWDV2I | USBPHY_PWD_TXPWDIBIAS |
		USBPHY_PWD_TXPWDFS;
	writel(tmp, &port->phy_regs->hw_usbphy_pwd);

	/* Disable USB clock */
	ret = ehci_mxs_toggle_clock(port, 0);

	return ret;
}
