// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2009
 * Marvell Semiconductor <www.marvell.com>
 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
 */

#include <common.h>
#include <log.h>
#include <asm/io.h>
#include <usb.h>
#include <linux/delay.h>
#include "ehci.h"
#include <linux/mbus.h>
#include <asm/arch/cpu.h>
#include <dm.h>

#if defined(CONFIG_ARCH_KIRKWOOD)
#include <asm/arch/soc.h>
#elif defined(CONFIG_ARCH_ORION5X)
#include <asm/arch/orion5x.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

#define USB_WINDOW_CTRL(i)	(0x320 + ((i) << 4))
#define USB_WINDOW_BASE(i)	(0x324 + ((i) << 4))
#define USB_TARGET_DRAM		0x0

#define USB2_SBUSCFG_OFF	0x90

#define USB_SBUSCFG_BAWR_OFF	0x6
#define USB_SBUSCFG_BARD_OFF	0x3
#define USB_SBUSCFG_AHBBRST_OFF	0x0

#define USB_SBUSCFG_BAWR_ALIGN_64B	0x4
#define USB_SBUSCFG_BARD_ALIGN_64B	0x4
#define USB_SBUSCFG_AHBBRST_INCR16	0x7

/*
 * USB 2.0 Bridge Address Decoding registers setup
 */
#if CONFIG_IS_ENABLED(DM_USB)

struct ehci_mvebu_priv {
	struct ehci_ctrl ehci;
	fdt_addr_t hcd_base;
};

/*
 * Once all the older Marvell SoC's (Orion, Kirkwood) are converted
 * to the common mvebu archticture including the mbus setup, this
 * will be the only function needed to configure the access windows
 */
static void usb_brg_adrdec_setup(void *base)
{
	const struct mbus_dram_target_info *dram;
	int i;

	dram = mvebu_mbus_dram_info();

	for (i = 0; i < 4; i++) {
		writel(0, base + USB_WINDOW_CTRL(i));
		writel(0, base + USB_WINDOW_BASE(i));
	}

	for (i = 0; i < dram->num_cs; i++) {
		const struct mbus_dram_window *cs = dram->cs + i;

		/* Write size, attributes and target id to control register */
		writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
		       (dram->mbus_dram_target_id << 4) | 1,
		       base + USB_WINDOW_CTRL(i));

		/* Write base address to base register */
		writel(cs->base, base + USB_WINDOW_BASE(i));
	}
}

static void marvell_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
				       uint32_t *status_reg, uint32_t *reg)
{
	struct ehci_mvebu_priv *priv = ctrl->priv;

	/*
	 * Set default value for reg SBUSCFG, which is Control for the AMBA
	 * system bus interface:
	 * BAWR = BARD = 4 : Align rd/wr bursts packets larger than 64 bytes
	 * AHBBRST = 7     : Align AHB burst for packets larger than 64 bytes
	 */
	writel((USB_SBUSCFG_BAWR_ALIGN_64B << USB_SBUSCFG_BAWR_OFF) |
	       (USB_SBUSCFG_BARD_ALIGN_64B << USB_SBUSCFG_BARD_OFF) |
	       (USB_SBUSCFG_AHBBRST_INCR16 << USB_SBUSCFG_AHBBRST_OFF),
	       priv->hcd_base + USB2_SBUSCFG_OFF);

	mdelay(50);
}

static struct ehci_ops marvell_ehci_ops = {
	.powerup_fixup	= NULL,
};

static int ehci_mvebu_probe(struct udevice *dev)
{
	struct ehci_mvebu_priv *priv = dev_get_priv(dev);
	struct ehci_hccr *hccr;
	struct ehci_hcor *hcor;

	/*
	 * Get the base address for EHCI controller from the device node
	 */
	priv->hcd_base = dev_read_addr(dev);
	if (priv->hcd_base == FDT_ADDR_T_NONE) {
		debug("Can't get the EHCI register base address\n");
		return -ENXIO;
	}

	/*
	 * For SoCs without hlock like Armada3700 we need to program the sbuscfg
	 * reg to guarantee AHB master's burst will not overrun or underrun
	 * the FIFO. Otherwise all USB2 write option will fail.
	 * Also, the address decoder doesn't need to get setup with this
	 * SoC, so don't call usb_brg_adrdec_setup().
	 */
	if (device_is_compatible(dev, "marvell,armada3700-ehci"))
		marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup;
	else
		usb_brg_adrdec_setup((void *)priv->hcd_base);

	hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100);
	hcor = (struct ehci_hcor *)
		((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));

	debug("ehci-marvell: init hccr %lx and hcor %lx hc_length %ld\n",
	      (uintptr_t)hccr, (uintptr_t)hcor,
	      (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));

	return ehci_register(dev, hccr, hcor, &marvell_ehci_ops, 0,
			     USB_INIT_HOST);
}

static const struct udevice_id ehci_usb_ids[] = {
	{ .compatible = "marvell,orion-ehci", },
	{ .compatible = "marvell,armada3700-ehci", },
	{ }
};

U_BOOT_DRIVER(ehci_mvebu) = {
	.name	= "ehci_mvebu",
	.id	= UCLASS_USB,
	.of_match = ehci_usb_ids,
	.probe = ehci_mvebu_probe,
	.remove = ehci_deregister,
	.ops	= &ehci_usb_ops,
	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
	.priv_auto_alloc_size = sizeof(struct ehci_mvebu_priv),
	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
};

#else
#define MVUSB_BASE(port)	MVUSB0_BASE

static void usb_brg_adrdec_setup(int index)
{
	int i;
	u32 size, base, attrib;

	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {

		/* Enable DRAM bank */
		switch (i) {
		case 0:
			attrib = MVUSB0_CPU_ATTR_DRAM_CS0;
			break;
		case 1:
			attrib = MVUSB0_CPU_ATTR_DRAM_CS1;
			break;
		case 2:
			attrib = MVUSB0_CPU_ATTR_DRAM_CS2;
			break;
		case 3:
			attrib = MVUSB0_CPU_ATTR_DRAM_CS3;
			break;
		default:
			/* invalide bank, disable access */
			attrib = 0;
			break;
		}

		size = gd->bd->bi_dram[i].size;
		base = gd->bd->bi_dram[i].start;
		if ((size) && (attrib))
			writel(MVCPU_WIN_CTRL_DATA(size, USB_TARGET_DRAM,
						   attrib, MVCPU_WIN_ENABLE),
				MVUSB0_BASE + USB_WINDOW_CTRL(i));
		else
			writel(MVCPU_WIN_DISABLE,
			       MVUSB0_BASE + USB_WINDOW_CTRL(i));

		writel(base, MVUSB0_BASE + USB_WINDOW_BASE(i));
	}
}

/*
 * Create the appropriate control structures to manage
 * a new EHCI host controller.
 */
int ehci_hcd_init(int index, enum usb_init_type init,
		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	usb_brg_adrdec_setup(index);

	*hccr = (struct ehci_hccr *)(MVUSB_BASE(index) + 0x100);
	*hcor = (struct ehci_hcor *)((uint32_t) *hccr
			+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));

	debug("ehci-marvell: init hccr %x and hcor %x hc_length %d\n",
		(uint32_t)*hccr, (uint32_t)*hcor,
		(uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));

	return 0;
}

/*
 * Destroy the appropriate control structures corresponding
 * the the EHCI host controller.
 */
int ehci_hcd_stop(int index)
{
	return 0;
}

#endif /* CONFIG_IS_ENABLED(DM_USB) */
