From f9f020a4098ee40cbdaf3a58d8e20ec208285eb0 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 23 Nov 2018 19:43:18 +0000 Subject: Derive PHY class to new one specialized for USB PHY functions. Submitted by: mmel --- sys/conf/files | 2 + sys/dev/extres/phy/phy.c | 51 +----------- sys/dev/extres/phy/phy_internal.h | 83 ++++++++++++++++++++ sys/dev/extres/phy/phy_usb.c | 149 ++++++++++++++++++++++++++++++++++++ sys/dev/extres/phy/phy_usb.h | 85 ++++++++++++++++++++ sys/dev/extres/phy/phynode_usb_if.m | 51 ++++++++++++ 6 files changed, 371 insertions(+), 50 deletions(-) create mode 100644 sys/dev/extres/phy/phy_internal.h create mode 100644 sys/dev/extres/phy/phy_usb.c create mode 100644 sys/dev/extres/phy/phy_usb.h create mode 100644 sys/dev/extres/phy/phynode_usb_if.m (limited to 'sys') diff --git a/sys/conf/files b/sys/conf/files index c5738da28c8f..ca55496c573b 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1734,6 +1734,8 @@ dev/extres/clk/clk_mux.c optional ext_resources clk fdt dev/extres/phy/phy.c optional ext_resources phy fdt dev/extres/phy/phydev_if.m optional ext_resources phy fdt dev/extres/phy/phynode_if.m optional ext_resources phy fdt +dev/extres/phy/phy_usb.c optional ext_resources phy fdt +dev/extres/phy/phynode_usb_if.m optional ext_resources phy fdt dev/extres/hwreset/hwreset.c optional ext_resources hwreset fdt dev/extres/hwreset/hwreset_if.m optional ext_resources hwreset fdt dev/extres/nvmem/nvmem.c optional ext_resources nvmem fdt diff --git a/sys/dev/extres/phy/phy.c b/sys/dev/extres/phy/phy.c index 35090f1832d3..ab0929036c57 100644 --- a/sys/dev/extres/phy/phy.c +++ b/sys/dev/extres/phy/phy.c @@ -43,18 +43,12 @@ __FBSDID("$FreeBSD$"); #endif #include +#include #include "phydev_if.h" MALLOC_DEFINE(M_PHY, "phy", "Phy framework"); -/* Forward declarations. */ -struct phy; -struct phynode; - -typedef TAILQ_HEAD(phynode_list, phynode) phynode_list_t; -typedef TAILQ_HEAD(phy_list, phy) phy_list_t; - /* Default phy methods. */ static int phynode_method_init(struct phynode *phynode); static int phynode_method_enable(struct phynode *phynode, bool disable); @@ -73,53 +67,10 @@ static phynode_method_t phynode_methods[] = { }; DEFINE_CLASS_0(phynode, phynode_class, phynode_methods, 0); -/* - * Phy node - */ -struct phynode { - KOBJ_FIELDS; - - TAILQ_ENTRY(phynode) phylist_link; /* Global list entry */ - phy_list_t consumers_list; /* Consumers list */ - - - /* Details of this device. */ - const char *name; /* Globally unique name */ - - device_t pdev; /* Producer device_t */ - void *softc; /* Producer softc */ - intptr_t id; /* Per producer unique id */ -#ifdef FDT - phandle_t ofw_node; /* OFW node of phy */ -#endif - struct sx lock; /* Lock for this phy */ - int ref_cnt; /* Reference counter */ - int enable_cnt; /* Enabled counter */ -}; - -struct phy { - device_t cdev; /* consumer device*/ - struct phynode *phynode; - TAILQ_ENTRY(phy) link; /* Consumers list entry */ - - int enable_cnt; -}; - static phynode_list_t phynode_list = TAILQ_HEAD_INITIALIZER(phynode_list); -static struct sx phynode_topo_lock; SX_SYSINIT(phy_topology, &phynode_topo_lock, "Phy topology lock"); -#define PHY_TOPO_SLOCK() sx_slock(&phynode_topo_lock) -#define PHY_TOPO_XLOCK() sx_xlock(&phynode_topo_lock) -#define PHY_TOPO_UNLOCK() sx_unlock(&phynode_topo_lock) -#define PHY_TOPO_ASSERT() sx_assert(&phynode_topo_lock, SA_LOCKED) -#define PHY_TOPO_XASSERT() sx_assert(&phynode_topo_lock, SA_XLOCKED) - -#define PHYNODE_SLOCK(_sc) sx_slock(&((_sc)->lock)) -#define PHYNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock)) -#define PHYNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock)) - /* ---------------------------------------------------------------------------- * * Default phy methods for base class. diff --git a/sys/dev/extres/phy/phy_internal.h b/sys/dev/extres/phy/phy_internal.h new file mode 100644 index 000000000000..c2b985d68406 --- /dev/null +++ b/sys/dev/extres/phy/phy_internal.h @@ -0,0 +1,83 @@ +/*- + * Copyright 2018 Michal Meloun + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef DEV_EXTRES_PHY_INTERNAL_H +#define DEV_EXTRES_PHY_INTERNAL_H + +/* Forward declarations. */ +struct phy; +struct phynode; + +typedef TAILQ_HEAD(phynode_list, phynode) phynode_list_t; +typedef TAILQ_HEAD(phy_list, phy) phy_list_t; + +/* + * Phy node + */ +struct phynode { + KOBJ_FIELDS; + + TAILQ_ENTRY(phynode) phylist_link; /* Global list entry */ + phy_list_t consumers_list; /* Consumers list */ + + + /* Details of this device. */ + const char *name; /* Globally unique name */ + + device_t pdev; /* Producer device_t */ + void *softc; /* Producer softc */ + intptr_t id; /* Per producer unique id */ +#ifdef FDT + phandle_t ofw_node; /* OFW node of phy */ +#endif + struct sx lock; /* Lock for this phy */ + int ref_cnt; /* Reference counter */ + int enable_cnt; /* Enabled counter */ +}; + +struct phy { + device_t cdev; /* consumer device*/ + struct phynode *phynode; + TAILQ_ENTRY(phy) link; /* Consumers list entry */ + + int enable_cnt; +}; + + +#define PHY_TOPO_SLOCK() sx_slock(&phynode_topo_lock) +#define PHY_TOPO_XLOCK() sx_xlock(&phynode_topo_lock) +#define PHY_TOPO_UNLOCK() sx_unlock(&phynode_topo_lock) +#define PHY_TOPO_ASSERT() sx_assert(&phynode_topo_lock, SA_LOCKED) +#define PHY_TOPO_XASSERT() sx_assert(&phynode_topo_lock, SA_XLOCKED) + +#define PHYNODE_SLOCK(_sc) sx_slock(&((_sc)->lock)) +#define PHYNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock)) +#define PHYNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock)) + +struct sx phynode_topo_lock; + +#endif /* DEV_EXTRES_PHY_INTERNAL_H */ diff --git a/sys/dev/extres/phy/phy_usb.c b/sys/dev/extres/phy/phy_usb.c new file mode 100644 index 000000000000..891db493634b --- /dev/null +++ b/sys/dev/extres/phy/phy_usb.c @@ -0,0 +1,149 @@ +/*- + * Copyright 2018 Michal Meloun + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + + +#include +#include + +#include "phydev_if.h" + +/* + * USB phy controller methods. + */ +static phynode_usb_method_t phynode_usb_methods[] = { + + PHYNODEUSBMETHOD_END +}; +DEFINE_CLASS_1(phynode_usb, phynode_usb_class, phynode_usb_methods, + 0, phynode_class); + +/* + * Create and initialize phy object, but do not register it. + */ +struct phynode * +phynode_usb_create(device_t pdev, phynode_class_t phynode_class, + struct phynode_usb_init_def *def) + +{ + struct phynode *phynode; + struct phynode_usb_sc *sc; + + phynode = phynode_create(pdev, phynode_class, &def->phynode_init_def); + if (phynode == NULL) + return (NULL); + sc = phynode_get_softc(phynode); + sc->std_param = def->std_param; + return (phynode); +} + +struct phynode +*phynode_usb_register(struct phynode *phynode) +{ + + return (phynode_register(phynode)); +} + +/* -------------------------------------------------------------------------- + * + * Real consumers executive + * + */ + +/* + * Set USB phy mode. (PHY_USB_MODE_*) + */ +int +phynode_usb_set_mode(struct phynode *phynode, int usb_mode) +{ + int rv; + + PHY_TOPO_ASSERT(); + + PHYNODE_XLOCK(phynode); + rv = PHYNODE_USB_SET_MODE(phynode, usb_mode); + PHYNODE_UNLOCK(phynode); + return (rv); +} + +/* + * Get USB phy mode. (PHY_USB_MODE_*) + */ +int +phynode_usb_get_mode(struct phynode *phynode, int *usb_mode) +{ + int rv; + + PHY_TOPO_ASSERT(); + + PHYNODE_XLOCK(phynode); + rv = PHYNODE_USB_GET_MODE(phynode, usb_mode); + PHYNODE_UNLOCK(phynode); + return (rv); +} + + /* -------------------------------------------------------------------------- + * + * USB phy consumers interface. + * + */ +int phy_usb_set_mode(phy_t phy, int usb_mode) +{ + int rv; + struct phynode *phynode; + + phynode = phy->phynode; + KASSERT(phynode->ref_cnt > 0, + ("Attempt to access unreferenced phy.\n")); + + PHY_TOPO_SLOCK(); + rv = phynode_usb_set_mode(phynode, usb_mode); + PHY_TOPO_UNLOCK(); + return (rv); +} + +int phy_usb_get_mode(phy_t phy, int *usb_mode) +{ + int rv; + struct phynode *phynode; + + phynode = phy->phynode; + KASSERT(phynode->ref_cnt > 0, + ("Attempt to access unreferenced phy.\n")); + + PHY_TOPO_SLOCK(); + rv = phynode_usb_get_mode(phynode, usb_mode); + PHY_TOPO_UNLOCK(); + return (rv); +} diff --git a/sys/dev/extres/phy/phy_usb.h b/sys/dev/extres/phy/phy_usb.h new file mode 100644 index 000000000000..7f391dd5f4bc --- /dev/null +++ b/sys/dev/extres/phy/phy_usb.h @@ -0,0 +1,85 @@ +/*- + * Copyright 2018 Michal Meloun + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DEV_EXTRES_PHY_USB_H_ +#define _DEV_EXTRES_PHY_USB_H_ + +#include +#include "phynode_usb_if.h" + +#define PHY_USB_MODE_UNKNOWN 0 +#define PHY_USB_MODE_HOST 1 +#define PHY_USB_MODE_OTG 2 +#define PHY_USB_MODE_DEVICE 3 + +/* Standard USB phy parameters. */ +struct phynode_usb_std_param { + int usb_mode; +}; + +struct phynode_usb_sc { + struct phynode_usb_std_param std_param; +}; + +/* Initialization parameters. */ +struct phynode_usb_init_def { + struct phynode_init_def phynode_init_def; + struct phynode_usb_std_param std_param; /* Standard parameters */ +}; + + +/* + * Shorthands for constructing method tables. + */ +#define PHYNODEUSBMETHOD KOBJMETHOD +#define PHYNODEUSBMETHOD_END KOBJMETHOD_END +#define phynode_usb_method_t kobj_method_t +#define phynode_usb_class_t kobj_class_t +DECLARE_CLASS(phynode_usb_class); + +struct phynode *phynode_usb_create(device_t pdev, phynode_class_t phynode_class, + struct phynode_usb_init_def *def); +struct phynode *phynode_usb_register(struct phynode *phynode); + +#if 0 +/* XXX to be implemented */ +#ifdef FDT +int phynode_usb_parse_ofw_stdparam(device_t dev, phandle_t node, + struct phynode_usb_init_def *def); +#endif +#endif + +/* Phynode functions. */ +int phynode_usb_set_mode(struct phynode *phynode, int usb_mode); +int phynode_usb_get_mode(struct phynode *phynode, int *usb_mode); + +/* Consumer functions. */ +int phy_usb_set_mode(phy_t phy, int usb_mode); +int phy_usb_get_mode(phy_t phy, int *usb_mode); + +#endif /*_DEV_EXTRES_PHY_USB_H_*/ diff --git a/sys/dev/extres/phy/phynode_usb_if.m b/sys/dev/extres/phy/phynode_usb_if.m new file mode 100644 index 000000000000..3622e2cc9938 --- /dev/null +++ b/sys/dev/extres/phy/phynode_usb_if.m @@ -0,0 +1,51 @@ +#- +# Copyright 2018 Michal Meloun +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +INTERFACE phynode_usb; + +HEADER { + struct phynode; +} + +# +# Set USB mode for phy +# Returns 0 on success or a standard errno value. +# +METHOD int set_mode { + struct phynode *phynode; + int usb_mode; /* PHY_USB_MODE_* */ +}; + +# +# Get USB mode +# Returns 0 on success or a standard errno value. +# +METHOD int get_mode { + struct phynode *phynode; + int *usb_mode; /* PHY_USB_MODE_* */ +}; -- cgit v1.2.3