// SPDX-License-Identifier: GPL-2.0
/*
 * Sonics Silicon Backplane
 * Broadcom USB-core driver  (SSB bus glue)
 *
 * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
 *
 * Based on ssb-ohci driver
 * Copyright 2007 Michael Buesch <m@bues.ch>
 *
 * Derived from the OHCI-PCI driver
 * Copyright 1999 Roman Weissgaerber
 * Copyright 2000-2002 David Brownell
 * Copyright 1999 Linus Torvalds
 * Copyright 1999 Gregory P. Smith
 *
 * Derived from the USBcore related parts of Broadcom-SB
 * Copyright 2005-2011 Broadcom Corporation
 */
#include <linux/ssb/ssb.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>

MODULE_AUTHOR("Hauke Mehrtens");
MODULE_DESCRIPTION("Common USB driver for SSB Bus");
MODULE_LICENSE("GPL");

#define SSB_HCD_TMSLOW_HOSTMODE	(1 << 29)

struct ssb_hcd_device {
	struct platform_device *ehci_dev;
	struct platform_device *ohci_dev;

	u32 enable_flags;
};

static void ssb_hcd_5354wa(struct ssb_device *dev)
{
#ifdef CONFIG_SSB_DRIVER_MIPS
	/* Work around for 5354 failures */
	if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
		/* Change syn01 reg */
		ssb_write32(dev, 0x894, 0x00fe00fe);

		/* Change syn03 reg */
		ssb_write32(dev, 0x89c, ssb_read32(dev, 0x89c) | 0x1);
	}
#endif
}

static void ssb_hcd_usb20wa(struct ssb_device *dev)
{
	if (dev->id.coreid == SSB_DEV_USB20_HOST) {
		/*
		 * USB 2.0 special considerations:
		 *
		 * In addition to the standard SSB reset sequence, the Host
		 * Control Register must be programmed to bring the USB core
		 * and various phy components out of reset.
		 */
		ssb_write32(dev, 0x200, 0x7ff);

		/* Change Flush control reg */
		ssb_write32(dev, 0x400, ssb_read32(dev, 0x400) & ~8);
		ssb_read32(dev, 0x400);

		/* Change Shim control reg */
		ssb_write32(dev, 0x304, ssb_read32(dev, 0x304) & ~0x100);
		ssb_read32(dev, 0x304);

		udelay(1);

		ssb_hcd_5354wa(dev);
	}
}

/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
static u32 ssb_hcd_init_chip(struct ssb_device *dev)
{
	u32 flags = 0;

	if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV)
		/* Put the device into host-mode. */
		flags |= SSB_HCD_TMSLOW_HOSTMODE;

	ssb_device_enable(dev, flags);

	ssb_hcd_usb20wa(dev);

	return flags;
}

static const struct usb_ehci_pdata ehci_pdata = {
};

static const struct usb_ohci_pdata ohci_pdata = {
};

static struct platform_device *ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
{
	struct platform_device *hci_dev;
	struct resource hci_res[2];
	int ret;

	memset(hci_res, 0, sizeof(hci_res));

	hci_res[0].start = addr;
	hci_res[0].end = hci_res[0].start + len - 1;
	hci_res[0].flags = IORESOURCE_MEM;

	hci_res[1].start = dev->irq;
	hci_res[1].flags = IORESOURCE_IRQ;

	hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
					"ehci-platform" , 0);
	if (!hci_dev)
		return ERR_PTR(-ENOMEM);

	hci_dev->dev.parent = dev->dev;
	hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;

	ret = platform_device_add_resources(hci_dev, hci_res,
					    ARRAY_SIZE(hci_res));
	if (ret)
		goto err_alloc;
	if (ohci)
		ret = platform_device_add_data(hci_dev, &ohci_pdata,
					       sizeof(ohci_pdata));
	else
		ret = platform_device_add_data(hci_dev, &ehci_pdata,
					       sizeof(ehci_pdata));
	if (ret)
		goto err_alloc;
	ret = platform_device_add(hci_dev);
	if (ret)
		goto err_alloc;

	return hci_dev;

err_alloc:
	platform_device_put(hci_dev);
	return ERR_PTR(ret);
}

static int ssb_hcd_probe(struct ssb_device *dev,
				   const struct ssb_device_id *id)
{
	int err, tmp;
	int start, len;
	u16 chipid_top;
	u16 coreid = dev->id.coreid;
	struct ssb_hcd_device *usb_dev;

	/* USBcores are only connected on embedded devices. */
	chipid_top = (dev->bus->chip_id & 0xFF00);
	if (chipid_top != 0x4700 && chipid_top != 0x5300)
		return -ENODEV;

	/* TODO: Probably need checks here; is the core connected? */

	if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))
		return -EOPNOTSUPP;

	usb_dev = devm_kzalloc(dev->dev, sizeof(struct ssb_hcd_device),
			       GFP_KERNEL);
	if (!usb_dev)
		return -ENOMEM;

	/* We currently always attach SSB_DEV_USB11_HOSTDEV
	 * as HOST OHCI. If we want to attach it as Client device,
	 * we must branch here and call into the (yet to
	 * be written) Client mode driver. Same for remove(). */
	usb_dev->enable_flags = ssb_hcd_init_chip(dev);

	tmp = ssb_read32(dev, SSB_ADMATCH0);

	start = ssb_admatch_base(tmp);
	len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp);
	usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len);
	if (IS_ERR(usb_dev->ohci_dev))
		return PTR_ERR(usb_dev->ohci_dev);

	if (coreid == SSB_DEV_USB20_HOST) {
		start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */
		usb_dev->ehci_dev = ssb_hcd_create_pdev(dev, false, start, len);
		if (IS_ERR(usb_dev->ehci_dev)) {
			err = PTR_ERR(usb_dev->ehci_dev);
			goto err_unregister_ohci_dev;
		}
	}

	ssb_set_drvdata(dev, usb_dev);
	return 0;

err_unregister_ohci_dev:
	platform_device_unregister(usb_dev->ohci_dev);
	return err;
}

static void ssb_hcd_remove(struct ssb_device *dev)
{
	struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
	struct platform_device *ohci_dev = usb_dev->ohci_dev;
	struct platform_device *ehci_dev = usb_dev->ehci_dev;

	if (ohci_dev)
		platform_device_unregister(ohci_dev);
	if (ehci_dev)
		platform_device_unregister(ehci_dev);

	ssb_device_disable(dev, 0);
}

static void ssb_hcd_shutdown(struct ssb_device *dev)
{
	ssb_device_disable(dev, 0);
}

#ifdef CONFIG_PM

static int ssb_hcd_suspend(struct ssb_device *dev, pm_message_t state)
{
	ssb_device_disable(dev, 0);

	return 0;
}

static int ssb_hcd_resume(struct ssb_device *dev)
{
	struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);

	ssb_device_enable(dev, usb_dev->enable_flags);

	return 0;
}

#else /* !CONFIG_PM */
#define ssb_hcd_suspend	NULL
#define ssb_hcd_resume	NULL
#endif /* CONFIG_PM */

static const struct ssb_device_id ssb_hcd_table[] = {
	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
	{},
};
MODULE_DEVICE_TABLE(ssb, ssb_hcd_table);

static struct ssb_driver ssb_hcd_driver = {
	.name		= KBUILD_MODNAME,
	.id_table	= ssb_hcd_table,
	.probe		= ssb_hcd_probe,
	.remove		= ssb_hcd_remove,
	.shutdown	= ssb_hcd_shutdown,
	.suspend	= ssb_hcd_suspend,
	.resume		= ssb_hcd_resume,
};

static int __init ssb_hcd_init(void)
{
	return ssb_driver_register(&ssb_hcd_driver);
}
module_init(ssb_hcd_init);

static void __exit ssb_hcd_exit(void)
{
	ssb_driver_unregister(&ssb_hcd_driver);
}
module_exit(ssb_hcd_exit);
