File Index
Files and directories
Sign in
FILE

usb_831x.c

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/platforms/83xx/usb_831x.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Freescale 83xx USB SOC setup code
  4 *
  5 * Copyright (C) 2007 Freescale Semiconductor, Inc.
  6 * Author: Li Yang
  7 */
  8
  9#include <linux/stddef.h>
 10#include <linux/kernel.h>
 11#include <linux/errno.h>
 12#include <linux/of.h>
 13#include <linux/of_address.h>
 14#include <linux/io.h>
 15
 16#include <sysdev/fsl_soc.h>
 17
 18#include "mpc83xx.h"
 19
 20int __init mpc831x_usb_cfg(void)
 21{
 22	u32 temp;
 23	void __iomem *immap, *usb_regs;
 24	struct device_node *np = NULL;
 25	struct device_node *immr_node = NULL;
 26	const void *prop;
 27	struct resource res;
 28	int ret = 0;
 29#ifdef CONFIG_USB_OTG
 30	const void *dr_mode;
 31#endif
 32
 33	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
 34	if (!np)
 35		return -ENODEV;
 36	prop = of_get_property(np, "phy_type", NULL);
 37
 38	/* Map IMMR space for pin and clock settings */
 39	immap = ioremap(get_immrbase(), 0x1000);
 40	if (!immap) {
 41		of_node_put(np);
 42		return -ENOMEM;
 43	}
 44
 45	/* Configure clock */
 46	immr_node = of_get_parent(np);
 47	if (immr_node && (of_device_is_compatible(immr_node, "fsl,mpc8315-immr") ||
 48			  of_device_is_compatible(immr_node, "fsl,mpc8308-immr")))
 49		clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
 50				MPC8315_SCCR_USB_MASK,
 51				MPC8315_SCCR_USB_DRCM_01);
 52	else
 53		clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
 54				MPC83XX_SCCR_USB_MASK,
 55				MPC83XX_SCCR_USB_DRCM_11);
 56
 57	/* Configure pin mux for ULPI.  There is no pin mux for UTMI */
 58	if (prop && !strcmp(prop, "ulpi")) {
 59		if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
 60			clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
 61					MPC8308_SICRH_USB_MASK,
 62					MPC8308_SICRH_USB_ULPI);
 63		} else if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) {
 64			clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
 65					MPC8315_SICRL_USB_MASK,
 66					MPC8315_SICRL_USB_ULPI);
 67			clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
 68					MPC8315_SICRH_USB_MASK,
 69					MPC8315_SICRH_USB_ULPI);
 70		} else {
 71			clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
 72					MPC831X_SICRL_USB_MASK,
 73					MPC831X_SICRL_USB_ULPI);
 74			clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
 75					MPC831X_SICRH_USB_MASK,
 76					MPC831X_SICRH_USB_ULPI);
 77		}
 78	}
 79
 80	iounmap(immap);
 81
 82	of_node_put(immr_node);
 83
 84	/* Map USB SOC space */
 85	ret = of_address_to_resource(np, 0, &res);
 86	if (ret) {
 87		of_node_put(np);
 88		return ret;
 89	}
 90	usb_regs = ioremap(res.start, resource_size(&res));
 91
 92	/* Using on-chip PHY */
 93	if (prop && (!strcmp(prop, "utmi_wide") || !strcmp(prop, "utmi"))) {
 94		u32 refsel;
 95
 96		if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr"))
 97			goto out;
 98
 99		if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
100			refsel = CONTROL_REFSEL_24MHZ;
101		else
102			refsel = CONTROL_REFSEL_48MHZ;
103		/* Set UTMI_PHY_EN and REFSEL */
104		out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
105			 CONTROL_UTMI_PHY_EN | refsel);
106	/* Using external UPLI PHY */
107	} else if (prop && !strcmp(prop, "ulpi")) {
108		/* Set PHY_CLK_SEL to ULPI */
109		temp = CONTROL_PHY_CLK_SEL_ULPI;
110#ifdef CONFIG_USB_OTG
111		/* Set OTG_PORT */
112		if (!of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
113			dr_mode = of_get_property(np, "dr_mode", NULL);
114			if (dr_mode && !strcmp(dr_mode, "otg"))
115				temp |= CONTROL_OTG_PORT;
116		}
117#endif /* CONFIG_USB_OTG */
118		out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
119	} else {
120		pr_warn("831x USB PHY type not supported\n");
121		ret = -EINVAL;
122	}
123
124out:
125	iounmap(usb_regs);
126	of_node_put(np);
127	return ret;
128}
~/ Read-only file preview.