// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Freescale 83xx USB SOC setup code
 *
 * Copyright (C) 2007 Freescale Semiconductor, Inc.
 * Author: Li Yang
 */


#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/of.h>

#include <asm/io.h>
#include <asm/prom.h>
#include <sysdev/fsl_soc.h>

#include "mpc83xx.h"


#ifdef CONFIG_PPC_MPC834x
int mpc834x_usb_cfg(void)
{
	unsigned long sccr, sicrl, sicrh;
	void __iomem *immap;
	struct device_node *np = NULL;
	int port0_is_dr = 0, port1_is_dr = 0;
	const void *prop, *dr_mode;

	immap = ioremap(get_immrbase(), 0x1000);
	if (!immap)
		return -ENOMEM;

	/* Read registers */
	/* Note: DR and MPH must use the same clock setting in SCCR */
	sccr = in_be32(immap + MPC83XX_SCCR_OFFS) & ~MPC83XX_SCCR_USB_MASK;
	sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) & ~MPC834X_SICRL_USB_MASK;
	sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) & ~MPC834X_SICRH_USB_UTMI;

	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
	if (np) {
		sccr |= MPC83XX_SCCR_USB_DRCM_11;  /* 1:3 */

		prop = of_get_property(np, "phy_type", NULL);
		port1_is_dr = 1;
		if (prop && (!strcmp(prop, "utmi") ||
					!strcmp(prop, "utmi_wide"))) {
			sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
			sicrh |= MPC834X_SICRH_USB_UTMI;
			port0_is_dr = 1;
		} else if (prop && !strcmp(prop, "serial")) {
			dr_mode = of_get_property(np, "dr_mode", NULL);
			if (dr_mode && !strcmp(dr_mode, "otg")) {
				sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
				port0_is_dr = 1;
			} else {
				sicrl |= MPC834X_SICRL_USB1;
			}
		} else if (prop && !strcmp(prop, "ulpi")) {
			sicrl |= MPC834X_SICRL_USB1;
		} else {
			printk(KERN_WARNING "834x USB PHY type not supported\n");
		}
		of_node_put(np);
	}
	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph");
	if (np) {
		sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */

		prop = of_get_property(np, "port0", NULL);
		if (prop) {
			if (port0_is_dr)
				printk(KERN_WARNING
					"834x USB port0 can't be used by both DR and MPH!\n");
			sicrl &= ~MPC834X_SICRL_USB0;
		}
		prop = of_get_property(np, "port1", NULL);
		if (prop) {
			if (port1_is_dr)
				printk(KERN_WARNING
					"834x USB port1 can't be used by both DR and MPH!\n");
			sicrl &= ~MPC834X_SICRL_USB1;
		}
		of_node_put(np);
	}

	/* Write back */
	out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
	out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
	out_be32(immap + MPC83XX_SICRH_OFFS, sicrh);

	iounmap(immap);
	return 0;
}
#endif /* CONFIG_PPC_MPC834x */

#ifdef CONFIG_PPC_MPC831x
int mpc831x_usb_cfg(void)
{
	u32 temp;
	void __iomem *immap, *usb_regs;
	struct device_node *np = NULL;
	struct device_node *immr_node = NULL;
	const void *prop;
	struct resource res;
	int ret = 0;
#ifdef CONFIG_USB_OTG
	const void *dr_mode;
#endif

	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
	if (!np)
		return -ENODEV;
	prop = of_get_property(np, "phy_type", NULL);

	/* Map IMMR space for pin and clock settings */
	immap = ioremap(get_immrbase(), 0x1000);
	if (!immap) {
		of_node_put(np);
		return -ENOMEM;
	}

	/* Configure clock */
	immr_node = of_get_parent(np);
	if (immr_node && (of_device_is_compatible(immr_node, "fsl,mpc8315-immr") ||
			of_device_is_compatible(immr_node, "fsl,mpc8308-immr")))
		clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
		                MPC8315_SCCR_USB_MASK,
		                MPC8315_SCCR_USB_DRCM_01);
	else
		clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
		                MPC83XX_SCCR_USB_MASK,
		                MPC83XX_SCCR_USB_DRCM_11);

	/* Configure pin mux for ULPI.  There is no pin mux for UTMI */
	if (prop && !strcmp(prop, "ulpi")) {
		if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
			clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
					MPC8308_SICRH_USB_MASK,
					MPC8308_SICRH_USB_ULPI);
		} else if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) {
			clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
					MPC8315_SICRL_USB_MASK,
					MPC8315_SICRL_USB_ULPI);
			clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
					MPC8315_SICRH_USB_MASK,
					MPC8315_SICRH_USB_ULPI);
		} else {
			clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
					MPC831X_SICRL_USB_MASK,
					MPC831X_SICRL_USB_ULPI);
			clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
					MPC831X_SICRH_USB_MASK,
					MPC831X_SICRH_USB_ULPI);
		}
	}

	iounmap(immap);

	of_node_put(immr_node);

	/* Map USB SOC space */
	ret = of_address_to_resource(np, 0, &res);
	if (ret) {
		of_node_put(np);
		return ret;
	}
	usb_regs = ioremap(res.start, resource_size(&res));

	/* Using on-chip PHY */
	if (prop && (!strcmp(prop, "utmi_wide") ||
		     !strcmp(prop, "utmi"))) {
		u32 refsel;

		if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr"))
			goto out;

		if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
			refsel = CONTROL_REFSEL_24MHZ;
		else
			refsel = CONTROL_REFSEL_48MHZ;
		/* Set UTMI_PHY_EN and REFSEL */
		out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
				CONTROL_UTMI_PHY_EN | refsel);
	/* Using external UPLI PHY */
	} else if (prop && !strcmp(prop, "ulpi")) {
		/* Set PHY_CLK_SEL to ULPI */
		temp = CONTROL_PHY_CLK_SEL_ULPI;
#ifdef CONFIG_USB_OTG
		/* Set OTG_PORT */
		if (!of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
			dr_mode = of_get_property(np, "dr_mode", NULL);
			if (dr_mode && !strcmp(dr_mode, "otg"))
				temp |= CONTROL_OTG_PORT;
		}
#endif /* CONFIG_USB_OTG */
		out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
	} else {
		printk(KERN_WARNING "831x USB PHY type not supported\n");
		ret = -EINVAL;
	}

out:
	iounmap(usb_regs);
	of_node_put(np);
	return ret;
}
#endif /* CONFIG_PPC_MPC831x */

#ifdef CONFIG_PPC_MPC837x
int mpc837x_usb_cfg(void)
{
	void __iomem *immap;
	struct device_node *np = NULL;
	const void *prop;
	int ret = 0;

	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
	if (!np || !of_device_is_available(np)) {
		of_node_put(np);
		return -ENODEV;
	}
	prop = of_get_property(np, "phy_type", NULL);

	if (!prop || (strcmp(prop, "ulpi") && strcmp(prop, "serial"))) {
		printk(KERN_WARNING "837x USB PHY type not supported\n");
		of_node_put(np);
		return -EINVAL;
	}

	/* Map IMMR space for pin and clock settings */
	immap = ioremap(get_immrbase(), 0x1000);
	if (!immap) {
		of_node_put(np);
		return -ENOMEM;
	}

	/* Configure clock */
	clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, MPC837X_SCCR_USB_DRCM_11,
			MPC837X_SCCR_USB_DRCM_11);

	/* Configure pin mux for ULPI/serial */
	clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USB_MASK,
			MPC837X_SICRL_USB_ULPI);

	iounmap(immap);
	of_node_put(np);
	return ret;
}
#endif /* CONFIG_PPC_MPC837x */
