// SPDX-License-Identifier: GPL-2.0
/*
 * host.c - ChipIdea USB host controller driver
 *
 * Copyright (c) 2012 Intel Corporation
 *
 * Author: Alexander Shishkin
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/chipidea.h>
#include <linux/regulator/consumer.h>
#include <linux/imx_gpc.h>

#include "../host/ehci.h"

#include "ci.h"
#include "bits.h"
#include "host.h"

static struct hc_driver __read_mostly ci_ehci_hc_driver;
static int (*orig_bus_suspend)(struct usb_hcd *hcd);
static int (*orig_bus_resume)(struct usb_hcd *hcd);
static int (*orig_hub_control)(struct usb_hcd *hcd,
				u16 typeReq, u16 wValue, u16 wIndex,
				char *buf, u16 wLength);

struct ehci_ci_priv {
	struct regulator *reg_vbus;
};

/* This function is used to override WKCN, WKDN, and WKOC */
static void ci_ehci_override_wakeup_flag(struct ehci_hcd *ehci,
		u32 __iomem *reg, u32 flags, bool set)
{
	u32 val = ehci_readl(ehci, reg);

	if (set)
		val |= flags;
	else
		val &= ~flags;

	ehci_writel(ehci, val, reg);
}

static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
{
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
	struct device *dev = hcd->self.controller;
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	int ret = 0;
	int port = HCS_N_PORTS(ehci->hcs_params);

	if (priv->reg_vbus) {
		if (port > 1) {
			dev_warn(dev,
				"Not support multi-port regulator control\n");
			return 0;
		}
		if (enable)
			ret = regulator_enable(priv->reg_vbus);
		else
			ret = regulator_disable(priv->reg_vbus);
		if (ret) {
			dev_err(dev,
				"Failed to %s vbus regulator, ret=%d\n",
				enable ? "enable" : "disable", ret);
			return ret;
		}
	}

	if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {
		/*
		 * Marvell 28nm HSIC PHY requires forcing the port to HS mode.
		 * As HSIC is always HS, this should be safe for others.
		 */
		hw_port_test_set(ci, 5);
		hw_port_test_set(ci, 0);
	}
	return 0;
};

static int ehci_ci_reset(struct usb_hcd *hcd)
{
	struct device *dev = hcd->self.controller;
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	int ret;

	ret = ehci_setup(hcd);
	if (ret)
		return ret;

	ehci->need_io_watchdog = 0;

	if (ci->platdata->notify_event) {
		ret = ci->platdata->notify_event(ci,
				CI_HDRC_CONTROLLER_RESET_EVENT);
		if (ret)
			return ret;
	}

	ci_platform_configure(ci);

	return ret;
}

static const struct ehci_driver_overrides ehci_ci_overrides = {
	.extra_priv_size = sizeof(struct ehci_ci_priv),
	.port_power	 = ehci_ci_portpower,
	.reset		 = ehci_ci_reset,
};

static int ci_imx_ehci_bus_resume(struct usb_hcd *hcd)
{
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	int port;

	int ret = orig_bus_resume(hcd);

	if (ret)
		return ret;

	port = HCS_N_PORTS(ehci->hcs_params);
	while (port--) {
		u32 __iomem *reg = &ehci->regs->port_status[port];
		u32 portsc = ehci_readl(ehci, reg);
		/*
		 * Notify PHY after resume signal has finished, it is
		 * for global suspend case.
		 */
		if (hcd->usb_phy
			&& test_bit(port, &ehci->bus_suspended)
			&& (portsc & PORT_CONNECT)
			&& (ehci_port_speed(ehci, portsc) ==
				USB_PORT_STAT_HIGH_SPEED))
			/* notify the USB PHY */
			usb_phy_notify_resume(hcd->usb_phy, USB_SPEED_HIGH);
	}

	return 0;
}

#ifdef CONFIG_USB_OTG

static int ci_start_port_reset(struct usb_hcd *hcd, unsigned port)
{
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	u32 __iomem *reg;
	u32 status;

	if (!port)
		return -EINVAL;
	port--;
	/* start port reset before HNP protocol time out */
	reg = &ehci->regs->port_status[port];
	status = ehci_readl(ehci, reg);
	if (!(status & PORT_CONNECT))
		return -ENODEV;

	/* khubd will finish the reset later */
	if (ehci_is_TDI(ehci))
		ehci_writel(ehci, status | (PORT_RESET & ~PORT_RWC_BITS), reg);
	else
		ehci_writel(ehci, status | PORT_RESET, reg);

	return 0;
}

#else

#define ci_start_port_reset    NULL

#endif

/* The below code is based on tegra ehci driver */
static int ci_imx_ehci_hub_control(
	struct usb_hcd	*hcd,
	u16		typeReq,
	u16		wValue,
	u16		wIndex,
	char		*buf,
	u16		wLength
)
{
	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
	u32 __iomem	*status_reg;
	u32		temp;
	unsigned long	flags;
	int		retval = 0;
	struct device *dev = hcd->self.controller;
	struct ci_hdrc *ci = dev_get_drvdata(dev);

	status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];

	spin_lock_irqsave(&ehci->lock, flags);

	if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
		temp = ehci_readl(ehci, status_reg);
		if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
			retval = -EPIPE;
			goto done;
		}

		temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
		temp |= PORT_WKDISC_E | PORT_WKOC_E;
		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);

		/*
		 * If a transaction is in progress, there may be a delay in
		 * suspending the port. Poll until the port is suspended.
		 */
		if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
						PORT_SUSPEND, 5000))
			ehci_err(ehci, "timeout waiting for SUSPEND\n");

		if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
			if (ci->platdata->notify_event)
				ci->platdata->notify_event
					(ci, CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
			ci_ehci_override_wakeup_flag(ehci, status_reg,
				PORT_WKDISC_E | PORT_WKCONN_E, false);
		}

		spin_unlock_irqrestore(&ehci->lock, flags);
		if (ehci_port_speed(ehci, temp) ==
				USB_PORT_STAT_HIGH_SPEED && hcd->usb_phy) {
			/* notify the USB PHY */
			usb_phy_notify_suspend(hcd->usb_phy, USB_SPEED_HIGH);
		}
		spin_lock_irqsave(&ehci->lock, flags);

		set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
		goto done;
	}

	/*
	 * After resume has finished, it needs do some post resume
	 * operation for some SoCs.
	 */
	else if (typeReq == ClearPortFeature &&
					wValue == USB_PORT_FEAT_C_SUSPEND) {

		/* Make sure the resume has finished, it should be finished */
		if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
			ehci_err(ehci, "timeout waiting for resume\n");

		temp = ehci_readl(ehci, status_reg);

		if (ehci_port_speed(ehci, temp) ==
				USB_PORT_STAT_HIGH_SPEED && hcd->usb_phy) {
			/* notify the USB PHY */
			usb_phy_notify_resume(hcd->usb_phy, USB_SPEED_HIGH);
		}
	}

	spin_unlock_irqrestore(&ehci->lock, flags);

	/* Handle the hub control events here */
	return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
done:
	spin_unlock_irqrestore(&ehci->lock, flags);
	return retval;
}

static irqreturn_t host_irq(struct ci_hdrc *ci)
{
	if (ci->hcd)
		return usb_hcd_irq(ci->irq, ci->hcd);
	else
		return IRQ_NONE;
}

static int host_start(struct ci_hdrc *ci)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct ehci_ci_priv *priv;
	int ret;

	if (usb_disabled())
		return -ENODEV;

	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
			       ci->dev, dev_name(ci->dev), NULL);
	if (!hcd)
		return -ENOMEM;

	dev_set_drvdata(ci->dev, ci);
	hcd->rsrc_start = ci->hw_bank.phys;
	hcd->rsrc_len = ci->hw_bank.size;
	hcd->regs = ci->hw_bank.abs;
	hcd->has_tt = 1;

	hcd->power_budget = ci->platdata->power_budget;
	hcd->tpl_support = ci->platdata->tpl_support;
	if (ci->phy)
		hcd->phy = ci->phy;
	else
		hcd->usb_phy = ci->usb_phy;

	ehci = hcd_to_ehci(hcd);
	ehci->caps = ci->hw_bank.cap;
	ehci->has_hostpc = ci->hw_bank.lpm;
	ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
	ehci->imx28_write_fix = ci->imx28_write_fix;

	priv = (struct ehci_ci_priv *)ehci->priv;
	priv->reg_vbus = NULL;

	if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
		if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
			ret = regulator_enable(ci->platdata->reg_vbus);
			if (ret) {
				dev_err(ci->dev,
				"Failed to enable vbus regulator, ret=%d\n",
									ret);
				goto put_hcd;
			}
		} else {
			priv->reg_vbus = ci->platdata->reg_vbus;
		}
	}

	if (ci_otg_is_fsm_mode(ci)) {
		if (ci->fsm.id && ci->fsm.otg->state <= OTG_STATE_B_HOST)
			hcd->self.is_b_host = 1;
		else
			hcd->self.is_b_host = 0;
	}

	ret = usb_add_hcd(hcd, 0, 0);
	if (ret) {
		goto disable_reg;
	} else {
		struct usb_otg *otg = &ci->otg;

		ci->hcd = hcd;

		if (ci_otg_is_fsm_mode(ci)) {
			hcd->self.otg_fsm = &ci->fsm;
			otg->host = &hcd->self;
			hcd->self.otg_port = 1;
		}
	}

	if (ci->platdata->notify_event &&
		(ci->platdata->flags & CI_HDRC_IMX_IS_HSIC))
		ci->platdata->notify_event
			(ci, CI_HDRC_IMX_HSIC_ACTIVE_EVENT);

	return ret;

disable_reg:
	if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
		regulator_disable(ci->platdata->reg_vbus);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}

static void host_stop(struct ci_hdrc *ci)
{
	struct usb_hcd *hcd = ci->hcd;

	if (hcd) {
		if (ci->platdata->notify_event)
			ci->platdata->notify_event(ci,
				CI_HDRC_CONTROLLER_STOPPED_EVENT);
		usb_remove_hcd(hcd);
		ci->role = CI_ROLE_END;
		synchronize_irq(ci->irq);
		usb_put_hcd(hcd);
		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
				regulator_disable(ci->platdata->reg_vbus);
		if (hcd->self.is_b_host)
			hcd->self.is_b_host = 0;
	}
	ci->hcd = NULL;
	ci->otg.host = NULL;
}

bool ci_hdrc_host_has_device(struct ci_hdrc *ci)
{
	struct usb_device *roothub;
	int i;

	if ((ci->role == CI_ROLE_HOST) && ci->hcd) {
		roothub = ci->hcd->self.root_hub;
		for (i = 0; i < roothub->maxchild; ++i) {
			if (usb_hub_find_child(roothub, (i + 1)))
				return true;
		}
	}
	return false;
}

static void ci_hdrc_host_save_for_power_lost(struct ci_hdrc *ci)
{
	struct ehci_hcd *ehci;

	if (!ci->hcd)
		return;

	ehci = hcd_to_ehci(ci->hcd);
	/* save EHCI registers */
	ci->pm_usbmode = ehci_readl(ehci, &ehci->regs->usbmode);
	ci->pm_command = ehci_readl(ehci, &ehci->regs->command);
	ci->pm_command &= ~CMD_RUN;
	ci->pm_status  = ehci_readl(ehci, &ehci->regs->status);
	ci->pm_intr_enable  = ehci_readl(ehci, &ehci->regs->intr_enable);
	ci->pm_frame_index  = ehci_readl(ehci, &ehci->regs->frame_index);
	ci->pm_segment  = ehci_readl(ehci, &ehci->regs->segment);
	ci->pm_frame_list  = ehci_readl(ehci, &ehci->regs->frame_list);
	ci->pm_async_next  = ehci_readl(ehci, &ehci->regs->async_next);
	ci->pm_configured_flag  =
			ehci_readl(ehci, &ehci->regs->configured_flag);
	ci->pm_portsc = ehci_readl(ehci, &ehci->regs->port_status[0]);
}

static void ci_hdrc_host_restore_from_power_lost(struct ci_hdrc *ci)
{
	struct ehci_hcd *ehci;
	unsigned long   flags;
	u32 tmp;
	int step_ms;
	/*
	 * If the vbus is off during system suspend, most of devices will pull
	 * DP up within 200ms when they see vbus, set 1000ms for safety.
	 */
	int timeout_ms = 1000;

	if (!ci->hcd)
		return;

	hw_controller_reset(ci);

	ehci = hcd_to_ehci(ci->hcd);
	spin_lock_irqsave(&ehci->lock, flags);
	/* Restore EHCI registers */
	ehci_writel(ehci, ci->pm_usbmode, &ehci->regs->usbmode);
	ehci_writel(ehci, ci->pm_portsc, &ehci->regs->port_status[0]);
	ehci_writel(ehci, ci->pm_command, &ehci->regs->command);
	ehci_writel(ehci, ci->pm_intr_enable, &ehci->regs->intr_enable);
	ehci_writel(ehci, ci->pm_frame_index, &ehci->regs->frame_index);
	ehci_writel(ehci, ci->pm_segment, &ehci->regs->segment);
	ehci_writel(ehci, ci->pm_frame_list, &ehci->regs->frame_list);
	ehci_writel(ehci, ci->pm_async_next, &ehci->regs->async_next);
	ehci_writel(ehci, ci->pm_configured_flag,
					&ehci->regs->configured_flag);
	/* Restore the PHY's connect notifier setting */
	if (ci->pm_portsc & PORTSC_HSP)
		usb_phy_notify_connect(ci->usb_phy, USB_SPEED_HIGH);

	tmp = ehci_readl(ehci, &ehci->regs->command);
	tmp |= CMD_RUN;
	ehci_writel(ehci, tmp, &ehci->regs->command);
	spin_unlock_irqrestore(&ehci->lock, flags);

	if (!(ci->pm_portsc & PORTSC_CCS))
		return;

	for (step_ms = 0; step_ms < timeout_ms; step_ms += 25) {
		if (ehci_readl(ehci, &ehci->regs->port_status[0]) & PORTSC_CCS)
			break;
		msleep(25);
	}
}

static void ci_hdrc_host_suspend(struct ci_hdrc *ci)
{
	if (ci_hdrc_host_has_device(ci))
		imx_gpc_mf_request_on(ci->irq, 1);

	ci_hdrc_host_save_for_power_lost(ci);
}

static void ci_hdrc_host_resume(struct ci_hdrc *ci, bool power_lost)
{
	imx_gpc_mf_request_on(ci->irq, 0);

	if (power_lost)
		ci_hdrc_host_restore_from_power_lost(ci);
}

void ci_hdrc_host_destroy(struct ci_hdrc *ci)
{
	if (ci->role == CI_ROLE_HOST && ci->hcd) {
		disable_irq_nosync(ci->irq);
		host_stop(ci);
		enable_irq(ci->irq);
	}
}

static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
{
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	int port;
	u32 tmp;
	struct device *dev = hcd->self.controller;
	struct ci_hdrc *ci = dev_get_drvdata(dev);

	int ret = orig_bus_suspend(hcd);

	if (ret)
		return ret;

	port = HCS_N_PORTS(ehci->hcs_params);
	while (port--) {
		u32 __iomem *reg = &ehci->regs->port_status[port];
		u32 portsc = ehci_readl(ehci, reg);

		if (portsc & PORT_CONNECT) {
			/*
			 * For chipidea, the resume signal will be ended
			 * automatically, so for remote wakeup case, the
			 * usbcmd.rs may not be set before the resume has
			 * ended if other resume paths consumes too much
			 * time (~24ms), in that case, the SOF will not
			 * send out within 3ms after resume ends, then the
			 * high speed device will enter full speed mode.
			 */

			tmp = ehci_readl(ehci, &ehci->regs->command);
			tmp |= CMD_RUN;
			ehci_writel(ehci, tmp, &ehci->regs->command);
			/*
			 * It needs a short delay between set RS bit and PHCD.
			 */
			usleep_range(150, 200);

			/*
			 * If a transaction is in progress, there may be
			 * a delay in suspending the port. Poll until the
			 * port is suspended.
			 */
			if (test_bit(port, &ehci->bus_suspended) &&
					ehci_handshake(ehci, reg, PORT_SUSPEND,
							PORT_SUSPEND, 5000))
				ehci_err(ehci, "timeout waiting for SUSPEND\n");

			if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC)
				ci_ehci_override_wakeup_flag(ehci, reg,
					PORT_WKDISC_E | PORT_WKCONN_E, false);

			if (hcd->usb_phy && test_bit(port, &ehci->bus_suspended)
				&& (ehci_port_speed(ehci, portsc) ==
					USB_PORT_STAT_HIGH_SPEED))
				/*
				 * notify the USB PHY, it is for global
				 * suspend case.
				 */
				usb_phy_notify_suspend(hcd->usb_phy,
					USB_SPEED_HIGH);
			break;
		}
	}

	return 0;
}

int ci_hdrc_host_init(struct ci_hdrc *ci)
{
	struct ci_role_driver *rdrv;

	if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_HC))
		return -ENXIO;

	rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
	if (!rdrv)
		return -ENOMEM;

	rdrv->start	= host_start;
	rdrv->stop	= host_stop;
	rdrv->irq	= host_irq;
	rdrv->suspend	= ci_hdrc_host_suspend;
	rdrv->resume	= ci_hdrc_host_resume;
	rdrv->name	= "host";
	ci->roles[CI_ROLE_HOST] = rdrv;

	return 0;
}

void ci_hdrc_host_driver_init(void)
{
	ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
	orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
	orig_bus_resume = ci_ehci_hc_driver.bus_resume;
	orig_hub_control = ci_ehci_hc_driver.hub_control;

	ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
	ci_ehci_hc_driver.bus_resume = ci_imx_ehci_bus_resume;
	ci_ehci_hc_driver.hub_control = ci_imx_ehci_hub_control;
	ci_ehci_hc_driver.start_port_reset = ci_start_port_reset;
}
