From owner-svn-src-all@freebsd.org Thu Mar 3 22:26:38 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 49A0AA944C5; Thu, 3 Mar 2016 22:26:38 +0000 (UTC) (envelope-from jmcneill@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0B7C6B59; Thu, 3 Mar 2016 22:26:37 +0000 (UTC) (envelope-from jmcneill@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u23MQbvp005503; Thu, 3 Mar 2016 22:26:37 GMT (envelope-from jmcneill@FreeBSD.org) Received: (from jmcneill@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u23MQbfO005502; Thu, 3 Mar 2016 22:26:37 GMT (envelope-from jmcneill@FreeBSD.org) Message-Id: <201603032226.u23MQbfO005502@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jmcneill set sender to jmcneill@FreeBSD.org using -f From: Jared McNeill Date: Thu, 3 Mar 2016 22:26:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r296365 - head/sys/dev/dwc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Mar 2016 22:26:38 -0000 Author: jmcneill Date: Thu Mar 3 22:26:36 2016 New Revision: 296365 URL: https://svnweb.freebsd.org/changeset/base/296365 Log: Add support for resetting the PHY via GPIO. Submitted by: Emmanuel Vadot Reviewed by: andrew, jmcneill Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D5505 Modified: head/sys/dev/dwc/if_dwc.c Modified: head/sys/dev/dwc/if_dwc.c ============================================================================== --- head/sys/dev/dwc/if_dwc.c Thu Mar 3 22:25:28 2016 (r296364) +++ head/sys/dev/dwc/if_dwc.c Thu Mar 3 22:26:36 2016 (r296365) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ __FBSDID("$FreeBSD$"); #include #include "if_dwc_if.h" +#include "gpio_if.h" #include "miibus_if.h" #define READ4(_sc, _reg) \ @@ -1010,6 +1012,62 @@ dwc_get_hwaddr(struct dwc_softc *sc, uin return (0); } +#define GPIO_ACTIVE_LOW 1 + +static int +dwc_reset(device_t dev) +{ + pcell_t gpio_prop[4]; + pcell_t delay_prop[3]; + phandle_t node, gpio_node; + device_t gpio; + uint32_t pin, flags; + uint32_t pin_value; + + node = ofw_bus_get_node(dev); + if (OF_getencprop(node, "snps,reset-gpio", + gpio_prop, sizeof(gpio_prop)) <= 0) + return (0); + + if (OF_getencprop(node, "snps,reset-delays-us", + delay_prop, sizeof(delay_prop)) <= 0) { + device_printf(dev, + "Wrong property for snps,reset-delays-us"); + return (ENXIO); + } + + gpio_node = OF_node_from_xref(gpio_prop[0]); + if ((gpio = OF_device_from_xref(gpio_prop[0])) == NULL) { + device_printf(dev, + "Can't find gpio controller for phy reset\n"); + return (ENXIO); + } + + if (GPIO_MAP_GPIOS(gpio, node, gpio_node, + sizeof(gpio_prop) / sizeof(gpio_prop[0]) - 1, + gpio_prop + 1, &pin, &flags) != 0) { + device_printf(dev, "Can't map gpio for phy reset\n"); + return (ENXIO); + } + + pin_value = GPIO_PIN_LOW; + if (OF_hasprop(node, "snps,reset-active-low")) + pin_value = GPIO_PIN_HIGH; + + if (flags & GPIO_ACTIVE_LOW) + pin_value = !pin_value; + + GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT); + GPIO_PIN_SET(gpio, pin, pin_value); + DELAY(delay_prop[0]); + GPIO_PIN_SET(gpio, pin, !pin_value); + DELAY(delay_prop[1]); + GPIO_PIN_SET(gpio, pin, pin_value); + DELAY(delay_prop[2]); + + return (0); +} + static int dwc_probe(device_t dev) { @@ -1058,6 +1116,12 @@ dwc_attach(device_t dev) return (ENXIO); } + /* Reset the PHY if needed */ + if (dwc_reset(dev) != 0) { + device_printf(dev, "Can't reset the PHY\n"); + return (ENXIO); + } + /* Reset */ reg = READ4(sc, BUS_MODE); reg |= (BUS_MODE_SWR);