From owner-svn-src-all@freebsd.org Thu Nov 15 17:05:04 2018 Return-Path: Delivered-To: svn-src-all@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 42B3E1103627; Thu, 15 Nov 2018 17:05:04 +0000 (UTC) (envelope-from loos@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 6DAC474CAA; Thu, 15 Nov 2018 17:05:03 +0000 (UTC) (envelope-from loos@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 5030211439; Thu, 15 Nov 2018 17:05:03 +0000 (UTC) (envelope-from loos@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wAFH53Di072227; Thu, 15 Nov 2018 17:05:03 GMT (envelope-from loos@FreeBSD.org) Received: (from loos@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wAFH53fH072226; Thu, 15 Nov 2018 17:05:03 GMT (envelope-from loos@FreeBSD.org) Message-Id: <201811151705.wAFH53fH072226@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: loos set sender to loos@FreeBSD.org using -f From: Luiz Otavio O Souza Date: Thu, 15 Nov 2018 17:05:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r340458 - head/sys/arm/mv X-SVN-Group: head X-SVN-Commit-Author: loos X-SVN-Commit-Paths: head/sys/arm/mv X-SVN-Commit-Revision: 340458 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 6DAC474CAA X-Spamd-Result: default: False [-106.87 / 200.00]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; ALLOW_DOMAIN_WHITELIST(-100.00)[FreeBSD.org]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; HAS_XAW(0.00)[]; R_SPF_SOFTFAIL(0.00)[~all]; DMARC_NA(0.00)[FreeBSD.org]; RCVD_COUNT_THREE(0.00)[4]; MX_GOOD(-0.01)[cached: mx1.FreeBSD.org]; NEURAL_HAM_SHORT(-0.99)[-0.992,0]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; RCVD_TLS_LAST(0.00)[]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; IP_SCORE(-3.77)[ip: (-9.91), ipnet: 2610:1c1:1::/48(-4.93), asn: 11403(-3.91), country: US(-0.10)] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 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, 15 Nov 2018 17:05:04 -0000 Author: loos Date: Thu Nov 15 17:05:02 2018 New Revision: 340458 URL: https://svnweb.freebsd.org/changeset/base/340458 Log: Set the SPI clock speed and polarity on each transfer to catch up with recent changes in spibus and allow the use of different SPI modes on the same bus. Reported by: ian Sponsored by: Rubicon Communications, LLC (Netgate) Modified: head/sys/arm/mv/mv_spi.c Modified: head/sys/arm/mv/mv_spi.c ============================================================================== --- head/sys/arm/mv/mv_spi.c Thu Nov 15 16:42:59 2018 (r340457) +++ head/sys/arm/mv/mv_spi.c Thu Nov 15 17:05:02 2018 (r340458) @@ -44,6 +44,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "spibus_if.h" struct mv_spi_softc { @@ -70,11 +72,23 @@ struct mv_spi_softc { #define MV_SPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define MV_SPI_CONTROL 0 +#define MV_SPI_CTRL_CS_MASK 7 #define MV_SPI_CTRL_CS_SHIFT 2 #define MV_SPI_CTRL_SMEMREADY (1 << 1) #define MV_SPI_CTRL_CS_ACTIVE (1 << 0) #define MV_SPI_CONF 0x4 +#define MV_SPI_CONF_MODE_SHIFT 12 +#define MV_SPI_CONF_MODE_MASK (3 << MV_SPI_CONF_MODE_SHIFT) #define MV_SPI_CONF_BYTELEN (1 << 5) +#define MV_SPI_CONF_CLOCK_SPR_MASK 0xf +#define MV_SPI_CONF_CLOCK_SPPR_MASK 1 +#define MV_SPI_CONF_CLOCK_SPPR_SHIFT 4 +#define MV_SPI_CONF_CLOCK_SPPRHI_MASK 3 +#define MV_SPI_CONF_CLOCK_SPPRHI_SHIFT 6 +#define MV_SPI_CONF_CLOCK_MASK \ + ((MV_SPI_CONF_CLOCK_SPPRHI_MASK << MV_SPI_CONF_CLOCK_SPPRHI_SHIFT) | \ + (MV_SPI_CONF_CLOCK_SPPR_MASK << MV_SPI_CONF_CLOCK_SPPR_SHIFT) | \ + MV_SPI_CONF_CLOCK_SPR_MASK) #define MV_SPI_DATAOUT 0x8 #define MV_SPI_DATAIN 0xc #define MV_SPI_INTR_STAT 0x10 @@ -244,10 +258,27 @@ mv_spi_intr(void *arg) } static int +mv_spi_psc_calc(uint32_t clock, uint32_t *spr, uint32_t *sppr) +{ + uint32_t divider, tclk; + + tclk = get_tclk_armada38x(); + for (*spr = 2; *spr <= 15; (*spr)++) { + for (*sppr = 0; *sppr <= 7; (*sppr)++) { + divider = *spr * (1 << *sppr); + if (tclk / divider <= clock) + return (0); + } + } + + return (EINVAL); +} + +static int mv_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { struct mv_spi_softc *sc; - uint32_t cs, reg; + uint32_t clock, cs, mode, reg, spr, sppr; int resid, timeout; KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, @@ -255,9 +286,23 @@ mv_spi_transfer(device_t dev, device_t child, struct s KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, ("TX/RX data sizes should be equal")); - /* Get the proper chip select for this child. */ + /* Get the proper chip select, mode and clock for this transfer. */ spibus_get_cs(child, &cs); cs &= ~SPIBUS_CS_HIGH; + spibus_get_mode(child, &mode); + if (mode > 3) { + device_printf(dev, + "Invalid mode %u requested by %s\n", mode, + device_get_nameunit(child)); + return (EINVAL); + } + spibus_get_clock(child, &clock); + if (clock == 0 || mv_spi_psc_calc(clock, &spr, &sppr) != 0) { + device_printf(dev, + "Invalid clock %uHz requested by %s\n", clock, + device_get_nameunit(child)); + return (EINVAL); + } sc = device_get_softc(dev); MV_SPI_LOCK(sc); @@ -275,7 +320,20 @@ mv_spi_transfer(device_t dev, device_t child, struct s sc->sc_written = 0; sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz; - MV_SPI_WRITE(sc, MV_SPI_CONTROL, cs << MV_SPI_CTRL_CS_SHIFT); + /* Set SPI Mode and Clock. */ + reg = MV_SPI_READ(sc, MV_SPI_CONF); + reg &= ~(MV_SPI_CONF_MODE_MASK | MV_SPI_CONF_CLOCK_MASK); + reg |= mode << MV_SPI_CONF_MODE_SHIFT; + reg |= spr & MV_SPI_CONF_CLOCK_SPR_MASK; + reg |= (sppr & MV_SPI_CONF_CLOCK_SPPR_MASK) << + MV_SPI_CONF_CLOCK_SPPR_SHIFT; + reg |= (sppr & MV_SPI_CONF_CLOCK_SPPRHI_MASK) << + MV_SPI_CONF_CLOCK_SPPRHI_SHIFT; + MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg); + + /* Set CS number and assert CS. */ + reg = (cs & MV_SPI_CTRL_CS_MASK) << MV_SPI_CTRL_CS_SHIFT; + MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg); reg = MV_SPI_READ(sc, MV_SPI_CONTROL); MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg | MV_SPI_CTRL_CS_ACTIVE);