Path: blob/master/arch/powerpc/platforms/83xx/usb_831x.c
26481 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Freescale 83xx USB SOC setup code3*4* Copyright (C) 2007 Freescale Semiconductor, Inc.5* Author: Li Yang6*/78#include <linux/stddef.h>9#include <linux/kernel.h>10#include <linux/errno.h>11#include <linux/of.h>12#include <linux/of_address.h>13#include <linux/io.h>1415#include <sysdev/fsl_soc.h>1617#include "mpc83xx.h"1819int __init mpc831x_usb_cfg(void)20{21u32 temp;22void __iomem *immap, *usb_regs;23struct device_node *np = NULL;24struct device_node *immr_node = NULL;25const void *prop;26struct resource res;27int ret = 0;28#ifdef CONFIG_USB_OTG29const void *dr_mode;30#endif3132np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");33if (!np)34return -ENODEV;35prop = of_get_property(np, "phy_type", NULL);3637/* Map IMMR space for pin and clock settings */38immap = ioremap(get_immrbase(), 0x1000);39if (!immap) {40of_node_put(np);41return -ENOMEM;42}4344/* Configure clock */45immr_node = of_get_parent(np);46if (immr_node && (of_device_is_compatible(immr_node, "fsl,mpc8315-immr") ||47of_device_is_compatible(immr_node, "fsl,mpc8308-immr")))48clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,49MPC8315_SCCR_USB_MASK,50MPC8315_SCCR_USB_DRCM_01);51else52clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,53MPC83XX_SCCR_USB_MASK,54MPC83XX_SCCR_USB_DRCM_11);5556/* Configure pin mux for ULPI. There is no pin mux for UTMI */57if (prop && !strcmp(prop, "ulpi")) {58if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {59clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,60MPC8308_SICRH_USB_MASK,61MPC8308_SICRH_USB_ULPI);62} else if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) {63clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,64MPC8315_SICRL_USB_MASK,65MPC8315_SICRL_USB_ULPI);66clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,67MPC8315_SICRH_USB_MASK,68MPC8315_SICRH_USB_ULPI);69} else {70clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,71MPC831X_SICRL_USB_MASK,72MPC831X_SICRL_USB_ULPI);73clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,74MPC831X_SICRH_USB_MASK,75MPC831X_SICRH_USB_ULPI);76}77}7879iounmap(immap);8081of_node_put(immr_node);8283/* Map USB SOC space */84ret = of_address_to_resource(np, 0, &res);85if (ret) {86of_node_put(np);87return ret;88}89usb_regs = ioremap(res.start, resource_size(&res));9091/* Using on-chip PHY */92if (prop && (!strcmp(prop, "utmi_wide") || !strcmp(prop, "utmi"))) {93u32 refsel;9495if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr"))96goto out;9798if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))99refsel = CONTROL_REFSEL_24MHZ;100else101refsel = CONTROL_REFSEL_48MHZ;102/* Set UTMI_PHY_EN and REFSEL */103out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,104CONTROL_UTMI_PHY_EN | refsel);105/* Using external UPLI PHY */106} else if (prop && !strcmp(prop, "ulpi")) {107/* Set PHY_CLK_SEL to ULPI */108temp = CONTROL_PHY_CLK_SEL_ULPI;109#ifdef CONFIG_USB_OTG110/* Set OTG_PORT */111if (!of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {112dr_mode = of_get_property(np, "dr_mode", NULL);113if (dr_mode && !strcmp(dr_mode, "otg"))114temp |= CONTROL_OTG_PORT;115}116#endif /* CONFIG_USB_OTG */117out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);118} else {119pr_warn("831x USB PHY type not supported\n");120ret = -EINVAL;121}122123out:124iounmap(usb_regs);125of_node_put(np);126return ret;127}128129130