162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Freescale 83xx USB SOC setup code
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2007 Freescale Semiconductor, Inc.
662306a36Sopenharmony_ci * Author: Li Yang
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/stddef.h>
1062306a36Sopenharmony_ci#include <linux/kernel.h>
1162306a36Sopenharmony_ci#include <linux/errno.h>
1262306a36Sopenharmony_ci#include <linux/of.h>
1362306a36Sopenharmony_ci#include <linux/of_address.h>
1462306a36Sopenharmony_ci#include <linux/io.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <sysdev/fsl_soc.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "mpc83xx.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciint __init mpc837x_usb_cfg(void)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	void __iomem *immap;
2362306a36Sopenharmony_ci	struct device_node *np = NULL;
2462306a36Sopenharmony_ci	const void *prop;
2562306a36Sopenharmony_ci	int ret = 0;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
2862306a36Sopenharmony_ci	if (!np || !of_device_is_available(np)) {
2962306a36Sopenharmony_ci		of_node_put(np);
3062306a36Sopenharmony_ci		return -ENODEV;
3162306a36Sopenharmony_ci	}
3262306a36Sopenharmony_ci	prop = of_get_property(np, "phy_type", NULL);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	if (!prop || (strcmp(prop, "ulpi") && strcmp(prop, "serial"))) {
3562306a36Sopenharmony_ci		pr_warn("837x USB PHY type not supported\n");
3662306a36Sopenharmony_ci		of_node_put(np);
3762306a36Sopenharmony_ci		return -EINVAL;
3862306a36Sopenharmony_ci	}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	/* Map IMMR space for pin and clock settings */
4162306a36Sopenharmony_ci	immap = ioremap(get_immrbase(), 0x1000);
4262306a36Sopenharmony_ci	if (!immap) {
4362306a36Sopenharmony_ci		of_node_put(np);
4462306a36Sopenharmony_ci		return -ENOMEM;
4562306a36Sopenharmony_ci	}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	/* Configure clock */
4862306a36Sopenharmony_ci	clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, MPC837X_SCCR_USB_DRCM_11,
4962306a36Sopenharmony_ci			MPC837X_SCCR_USB_DRCM_11);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/* Configure pin mux for ULPI/serial */
5262306a36Sopenharmony_ci	clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USB_MASK,
5362306a36Sopenharmony_ci			MPC837X_SICRL_USB_ULPI);
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	iounmap(immap);
5662306a36Sopenharmony_ci	of_node_put(np);
5762306a36Sopenharmony_ci	return ret;
5862306a36Sopenharmony_ci}
59