From owner-svn-src-head@freebsd.org Mon Apr 9 14:05:44 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A34E3F830C9; Mon, 9 Apr 2018 14:05:44 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DF9B6FBFC; Mon, 9 Apr 2018 14:05:44 +0000 (UTC) (envelope-from kevans@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 409AC1FAA4; Mon, 9 Apr 2018 14:05:44 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w39E5ipD049358; Mon, 9 Apr 2018 14:05:44 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w39E5in8049357; Mon, 9 Apr 2018 14:05:44 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201804091405.w39E5in8049357@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Mon, 9 Apr 2018 14:05:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332327 - head/sys/arm/allwinner X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: head/sys/arm/allwinner X-SVN-Commit-Revision: 332327 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Apr 2018 14:05:44 -0000 Author: kevans Date: Mon Apr 9 14:05:43 2018 New Revision: 332327 URL: https://svnweb.freebsd.org/changeset/base/332327 Log: if_awg: Add support for allwinner,{tx,rx}-delay-ps bindings Split out delay parsing into a separate function; we'll support both {tx,rx}-delay as well as the new versions. While here, validate that they're within the expected range and fail to attach if they are not. Assuming that we can clamp the delay is a bad idea that might result in a non-working awg anyways, so we'll fail early to make it easier to catch. This version also unsets the tx and rx delay registers unconditionally and then sets them if we read a non-zero delay. These delay properties should default to 0 if not specified, as declared in the binding documentation. Presumably the delays will be set via hardware configuration if they're not explicitly set in FDT. Modified: head/sys/arm/allwinner/if_awg.c Modified: head/sys/arm/allwinner/if_awg.c ============================================================================== --- head/sys/arm/allwinner/if_awg.c Mon Apr 9 13:32:12 2018 (r332326) +++ head/sys/arm/allwinner/if_awg.c Mon Apr 9 14:05:43 2018 (r332327) @@ -221,6 +221,8 @@ static struct resource_spec awg_spec[] = { static void awg_txeof(struct awg_softc *sc); +static int awg_parse_delay(device_t dev, uint32_t *tx_delay, + uint32_t *rx_delay); static uint32_t syscon_read_emac_clk_reg(device_t dev); static void syscon_write_emac_clk_reg(device_t dev, uint32_t val); static phandle_t awg_get_phy_node(device_t dev); @@ -1218,6 +1220,50 @@ awg_has_internal_phy(device_t dev) } static int +awg_parse_delay(device_t dev, uint32_t *tx_delay, uint32_t *rx_delay) +{ + phandle_t node; + uint32_t delay; + + if (tx_delay == NULL || rx_delay == NULL) + return (EINVAL); + *tx_delay = *rx_delay = 0; + node = ofw_bus_get_node(dev); + + if (OF_getencprop(node, "tx-delay", &delay, sizeof(delay)) >= 0) + *tx_delay = delay; + else if (OF_getencprop(node, "allwinner,tx-delay-ps", &delay, + sizeof(delay)) >= 0) { + if ((delay % 100) != 0) { + device_printf(dev, "tx-delay-ps is not a multiple of 100\n"); + return (EDOM); + } + *tx_delay = delay / 100; + } + if (*tx_delay > 7) { + device_printf(dev, "tx-delay out of range\n"); + return (ERANGE); + } + + if (OF_getencprop(node, "rx-delay", &delay, sizeof(delay)) >= 0) + *rx_delay = delay; + else if (OF_getencprop(node, "allwinner,rx-delay-ps", &delay, + sizeof(delay)) >= 0) { + if ((delay % 100) != 0) { + device_printf(dev, "rx-delay-ps is not within documented domain\n"); + return (EDOM); + } + *rx_delay = delay / 100; + } + if (*rx_delay > 31) { + device_printf(dev, "rx-delay out of range\n"); + return (ERANGE); + } + + return (0); +} + +static int awg_setup_phy(device_t dev) { struct awg_softc *sc; @@ -1260,16 +1306,22 @@ awg_setup_phy(device_t dev) else reg |= EMAC_CLK_PIT_MII | EMAC_CLK_SRC_MII; - if (OF_getencprop(node, "tx-delay", &tx_delay, - sizeof(tx_delay)) > 0) { - reg &= ~EMAC_CLK_ETXDC; + /* + * Fail attach if we fail to parse either of the delay + * parameters. If we don't have the proper delay to write to + * syscon, then awg likely won't function properly anyways. + * Lack of delay is not an error! + */ + error = awg_parse_delay(dev, &tx_delay, &rx_delay); + if (error != 0) + goto fail; + + /* Default to 0 and we'll increase it if we need to. */ + reg &= ~(EMAC_CLK_ETXDC | EMAC_CLK_ERXDC); + if (tx_delay > 0) reg |= (tx_delay << EMAC_CLK_ETXDC_SHIFT); - } - if (OF_getencprop(node, "rx-delay", &rx_delay, - sizeof(rx_delay)) > 0) { - reg &= ~EMAC_CLK_ERXDC; + if (rx_delay > 0) reg |= (rx_delay << EMAC_CLK_ERXDC_SHIFT); - } if (sc->type == EMAC_H3) { if (awg_has_internal_phy(dev)) {