/*
 *  EHCI HCD (Host Controller Driver) for USB.
 *
 *  Copyright (C) 2013,2014 Renesas Electronics Corporation
 *  Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
 *
 *  SPDX-License-Identifier:     GPL-2.0
 */

#include <common.h>
#include <asm/io.h>
#include <asm/arch/ehci-rmobile.h>
#include "ehci.h"

#if defined(CONFIG_R8A7740)
static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
	0xC6700000
};
#elif defined(CONFIG_R8A7790)
static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
	0xEE080000,	/* USB0 (EHCI) */
	0xEE0A0000,	/* USB1 */
	0xEE0C0000,	/* USB2 */
	0xEE000000	/* USB3 (USB3.0 Host)*/
};
#elif defined(CONFIG_R8A7791)
static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
	0xEE080000,	/* USB0 (EHCI) */
	0xEE0C0000,	/* USB1 */
	0xEE000000	/* USB3 (USB3.0 Host)*/
};
#elif defined(CONFIG_R8A7794)
static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
	0xEE080000,	/* USB0 (EHCI) */
	0xEE0C0000,	/* USB1 */
	/* R8A7794 does not have USB 3.0. */
};
#else
#error rmobile EHCI USB driver not supported on this platform
#endif

int ehci_hcd_stop(int index)
{
	int i;
	u32 base;
	struct ahbcom_pci_bridge *ahbcom_pci;

	base = usb_base_address[index];
	ahbcom_pci = (struct ahbcom_pci_bridge *)(base + AHBPCI_OFFSET);
	writel(0, &ahbcom_pci->ahb_bus_ctr);

	/* reset ehci */
	setbits_le32(base + EHCI_USBCMD, CMD_RESET);
	for (i = 100; i > 0; i--) {
		if (!(readl(base + EHCI_USBCMD) & CMD_RESET))
			break;
		udelay(100);
	}

	if (!i)
		printf("error : ehci(%d) reset failed.\n", index);

	if (index == (CONFIG_USB_MAX_CONTROLLER_COUNT - 1))
		setbits_le32(SMSTPCR7, SMSTPCR703);

	return 0;
}

int ehci_hcd_init(int index, enum usb_init_type init,
	struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	u32 base;
	u32 phys_base;
	struct rmobile_ehci_reg *rehci;
	struct ahbcom_pci_bridge *ahbcom_pci;
	struct ahbconf_pci_bridge *ahbconf_pci;
	struct ahb_pciconf *ahb_pciconf_ohci;
	struct ahb_pciconf *ahb_pciconf_ehci;
	uint32_t cap_base;

	base = usb_base_address[index];
	phys_base = base;
	if (index == 0)
		clrbits_le32(SMSTPCR7, SMSTPCR703);

	rehci = (struct rmobile_ehci_reg *)(base + EHCI_OFFSET);
	ahbcom_pci = (struct ahbcom_pci_bridge *)(base + AHBPCI_OFFSET);
	ahbconf_pci =
		(struct ahbconf_pci_bridge *)(base + PCI_CONF_AHBPCI_OFFSET);
	ahb_pciconf_ohci = (struct ahb_pciconf *)(base + PCI_CONF_OHCI_OFFSET);
	ahb_pciconf_ehci = (struct ahb_pciconf *)(base + PCI_CONF_EHCI_OFFSET);

	/* Clock & Reset & Direct Power Down */
	clrsetbits_le32(&ahbcom_pci->usbctr,
			(DIRPD | PCICLK_MASK | USBH_RST), USBCTR_WIN_SIZE_1GB);
	clrbits_le32(&ahbcom_pci->usbctr, PLL_RST);

	/* AHB-PCI Bridge Communication Registers */
	writel(AHB_BUS_CTR_INIT, &ahbcom_pci->ahb_bus_ctr);
	writel((CONFIG_SYS_SDRAM_BASE & 0xf0000000) | PCIAHB_WIN_PREFETCH,
	       &ahbcom_pci->pciahb_win1_ctr);
	writel(0xf0000000 | PCIAHB_WIN_PREFETCH,
	       &ahbcom_pci->pciahb_win2_ctr);
	writel(phys_base | PCIWIN2_PCICMD, &ahbcom_pci->ahbpci_win2_ctr);

	setbits_le32(&ahbcom_pci->pci_arbiter_ctr,
		     PCIBP_MODE | PCIREQ1 | PCIREQ0);

	/* PCI Configuration Registers for AHBPCI */
	writel(PCIWIN1_PCICMD | AHB_CFG_AHBPCI,
	       &ahbcom_pci->ahbpci_win1_ctr);
	writel(phys_base + AHBPCI_OFFSET, &ahbconf_pci->basead);
	writel(CONFIG_SYS_SDRAM_BASE & 0xf0000000, &ahbconf_pci->win1_basead);
	writel(0xf0000000, &ahbconf_pci->win2_basead);
	writel(SERREN | PERREN | MASTEREN | MEMEN,
	       &ahbconf_pci->cmnd_sts);

	/* PCI Configuration Registers for EHCI */
	writel(PCIWIN1_PCICMD | AHB_CFG_HOST, &ahbcom_pci->ahbpci_win1_ctr);
	writel(phys_base + OHCI_OFFSET, &ahb_pciconf_ohci->basead);
	writel(phys_base + EHCI_OFFSET, &ahb_pciconf_ehci->basead);
	writel(SERREN | PERREN | MASTEREN | MEMEN,
	       &ahb_pciconf_ohci->cmnd_sts);
	writel(SERREN | PERREN | MASTEREN | MEMEN,
	       &ahb_pciconf_ehci->cmnd_sts);

	/* Enable PCI interrupt */
	setbits_le32(&ahbcom_pci->pci_int_enable,
		     USBH_PMEEN | USBH_INTBEN | USBH_INTAEN);

	*hccr = (struct ehci_hccr *)((uint32_t)&rehci->hciversion);
	cap_base = ehci_readl(&(*hccr)->cr_capbase);
	*hcor = (struct ehci_hcor *)((uint32_t)*hccr + HC_LENGTH(cap_base));

	return 0;
}
