From owner-freebsd-arm@freebsd.org Sun Dec 30 15:34:12 2018 Return-Path: Delivered-To: freebsd-arm@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 DA304142BA7B for ; Sun, 30 Dec 2018 15:34:11 +0000 (UTC) (envelope-from toshi@ruby.ocn.ne.jp) Received: from mogw1022.ocn.ad.jp (mogw1022.ocn.ad.jp [153.149.231.28]) by mx1.freebsd.org (Postfix) with ESMTP id 25B0989AD0 for ; Sun, 30 Dec 2018 15:34:07 +0000 (UTC) (envelope-from toshi@ruby.ocn.ne.jp) Received: from mf-smf-unw007c2 (mf-smf-unw007c2.ocn.ad.jp [153.138.219.100]) by mogw1022.ocn.ad.jp (Postfix) with ESMTP id 58166A8023F; Mon, 31 Dec 2018 00:33:57 +0900 (JST) Received: from ocn-vc-mts-104c1.ocn.ad.jp ([153.138.237.81]) by mf-smf-unw007c2 with ESMTP id dcyogdv3UQXHCdd6DgZg7A; Mon, 31 Dec 2018 00:33:57 +0900 Received: from smtp.ocn.ne.jp ([153.149.227.134]) by ocn-vc-mts-104c1.ocn.ad.jp with ESMTP id dd6Dgk3pUq2v1dd6DgR5xS; Mon, 31 Dec 2018 00:33:57 +0900 Received: from localhost (p571097-ipngn200409sizuokaden.shizuoka.ocn.ne.jp [180.33.36.97]) by smtp.ocn.ne.jp (Postfix) with ESMTPA; Mon, 31 Dec 2018 00:33:57 +0900 (JST) Date: Mon, 31 Dec 2018 00:33:56 +0900 (JST) Message-Id: <20181231.003356.1147810385398844555.toshi@ruby.ocn.ne.jp> To: freebsd-arm@freebsd.org Subject: SPI start bit (9 bit) for BBB From: SAITOU Toshihide X-GPG-fingerprint: 34B3 0B6A 8520 F5B0 EBC7 69F6 C055 9F8A 0D49 F8FC X-Mailer: Mew version 6.8 on Emacs 26.1 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 25B0989AD0 X-Spamd-Bar: ++++++ Authentication-Results: mx1.freebsd.org; spf=pass (mx1.freebsd.org: domain of toshi@ruby.ocn.ne.jp designates 153.149.231.28 as permitted sender) smtp.mailfrom=toshi@ruby.ocn.ne.jp X-Spamd-Result: default: False [6.38 / 15.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCVD_COUNT_FIVE(0.00)[5]; FROM_HAS_DN(0.00)[]; R_SPF_ALLOW(0.00)[+ip4:153.149.231.0/26]; MV_CASE(0.50)[]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; DMARC_NA(0.00)[ocn.ne.jp]; NEURAL_SPAM_MEDIUM(0.98)[0.979,0]; RCPT_COUNT_ONE(0.00)[1]; BAD_REP_POLICIES(0.10)[]; RBL_VIRUSFREE_BOTNET(2.00)[28.231.149.153.bip.virusfree.cz : 127.0.0.2]; TO_MATCH_ENVRCPT_ALL(0.00)[]; MX_GOOD(-0.01)[mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp,mfgw1.ocn.ad.jp]; NEURAL_SPAM_LONG(0.98)[0.982,0]; MID_CONTAINS_FROM(1.00)[]; NEURAL_SPAM_SHORT(0.54)[0.541,0]; RCVD_NO_TLS_LAST(0.10)[]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:4713, ipnet:153.128.0.0/11, country:JP]; IP_SCORE(0.29)[ipnet: 153.128.0.0/11(2.09), asn: 4713(-0.55), country: JP(-0.09)] X-Spam: Yes X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Dec 2018 15:34:12 -0000 In 3-line serial protcol, there is a type using additional 1-bit to specify command or data. The BBB can handle this, so I can use with the following patch (unskillful and maybe side effects exist). I hope this will attract someones interest to implement this and also SPI frequency and mode. --- arm/ti/ti_spi.c.orig 2018-12-22 00:47:12.096034000 +0900 +++ arm/ti/ti_spi.c 2018-12-30 23:58:00.000000000 +0900 @@ -493,6 +493,7 @@ ti_spi_transfer(device_t dev, device_t child, struct s /* Disable the FIFO. */ TI_SPI_WRITE(sc, MCSPI_XFERLEVEL, 0); +#if 0 /* 8 bits word, d0 miso, d1 mosi, mode 0 and CS active low. */ reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs)); reg &= ~(MCSPI_CONF_FFER | MCSPI_CONF_FFEW | MCSPI_CONF_SBPOL | @@ -501,6 +502,7 @@ ti_spi_transfer(device_t dev, device_t child, struct s MCSPI_CONF_DMAW | MCSPI_CONF_EPOL); reg |= MCSPI_CONF_DPE0 | MCSPI_CONF_EPOL | MCSPI_CONF_WL8BITS; TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg); +#endif #if 0 /* Enable channel interrupts. */ @@ -558,6 +560,70 @@ ti_spi_get_node(device_t bus, device_t dev) return (ofw_bus_get_node(bus)); } +static int +ti_spi_sbe(device_t dev, device_t child, uint32_t *request) +{ + struct ti_spi_softc *sc; + uint32_t reg; + + sc = device_get_softc(dev); + + TI_SPI_LOCK(sc); + + /* If the controller is in use wait until it is available. */ + while (sc->sc_flags & TI_SPI_BUSY) + mtx_sleep(dev, &sc->sc_mtx, 0, "ti_spi", 0); + + /* Now we have control over SPI controller. */ + sc->sc_flags = TI_SPI_BUSY; + + reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs)); + if (*request) + reg |= MCSPI_CONF_SBE; + else + reg &= ~MCSPI_CONF_SBE; + TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg); + + /* Release the controller and wakeup the next thread waiting for it. */ + sc->sc_flags = 0; + wakeup_one(dev); + TI_SPI_UNLOCK(sc); + + return (0); +} + +static int +ti_spi_sbpol(device_t dev, device_t child, uint32_t *request) +{ + struct ti_spi_softc *sc; + uint32_t reg; + + sc = device_get_softc(dev); + + TI_SPI_LOCK(sc); + + /* If the controller is in use wait until it is available. */ + while (sc->sc_flags & TI_SPI_BUSY) + mtx_sleep(dev, &sc->sc_mtx, 0, "ti_spi", 0); + + /* Now we have control over SPI controller. */ + sc->sc_flags = TI_SPI_BUSY; + + reg = TI_SPI_READ(sc, MCSPI_CONF_CH(sc->sc_cs)); + if (*request) + reg |= MCSPI_CONF_SBPOL; + else + reg &= ~MCSPI_CONF_SBPOL; + TI_SPI_WRITE(sc, MCSPI_CONF_CH(sc->sc_cs), reg); + + /* Release the controller and wakeup the next thread waiting for it. */ + sc->sc_flags = 0; + wakeup_one(dev); + TI_SPI_UNLOCK(sc); + + return (0); +} + static device_method_t ti_spi_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ti_spi_probe), @@ -569,6 +635,10 @@ static device_method_t ti_spi_methods[] = { /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, ti_spi_get_node), + + /* provisional chip register interface for SBE and SBPOL */ + DEVMETHOD(spibus_sbe, ti_spi_sbe), + DEVMETHOD(spibus_sbpol, ti_spi_sbpol), DEVMETHOD_END }; --- dev/spibus/spibus.c.orig 2018-12-29 23:50:40.262296000 +0900 +++ dev/spibus/spibus.c 2018-12-30 23:58:00.000000000 +0900 @@ -226,6 +226,18 @@ spibus_transfer_impl(device_t dev, device_t child, str return (SPIBUS_TRANSFER(device_get_parent(dev), child, cmd)); } +static int +spibus_sbe_impl(device_t dev, device_t child, uint32_t *request) +{ + return (SPIBUS_SBE(device_get_parent(dev), child, request)); +} + +static int +spibus_sbpol_impl(device_t dev, device_t child, uint32_t *request) +{ + return (SPIBUS_SBPOL(device_get_parent(dev), child, request)); +} + static device_method_t spibus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, spibus_probe), @@ -247,6 +259,9 @@ static device_method_t spibus_methods[] = { /* spibus interface */ DEVMETHOD(spibus_transfer, spibus_transfer_impl), + + DEVMETHOD(spibus_sbe, spibus_sbe_impl), + DEVMETHOD(spibus_sbpol, spibus_sbpol_impl), DEVMETHOD_END }; --- dev/spibus/spibus_if.m.orig 2018-12-22 00:49:22.440211000 +0900 +++ dev/spibus/spibus_if.m 2018-12-30 23:58:00.000000000 +0900 @@ -39,3 +39,15 @@ METHOD int transfer { device_t child; struct spi_command *cmd; }; + +METHOD int sbe { + device_t dev; + device_t child; + uint32_t *request; +}; + +METHOD int sbpol { + device_t dev; + device_t child; + uint32_t *request; +}; --- dev/spibus/spigen.c.orig 2018-12-29 20:19:20.584696000 +0900 +++ dev/spibus/spigen.c 2018-12-30 23:58:00.000000000 +0900 @@ -248,6 +248,28 @@ spigen_transfer_mmapped(struct cdev *cdev, struct spig } static int +spigen_sbe(struct cdev *cdev, uint32_t *request) +{ + device_t dev = cdev->si_drv1; + int error = 0; + + error = SPIBUS_SBE(device_get_parent(dev), dev, (uint32_t *)request); + + return (error); +} + +static int +spigen_sbpol(struct cdev *cdev, uint32_t *request) +{ + device_t dev = cdev->si_drv1; + int error = 0; + + error = SPIBUS_SBPOL(device_get_parent(dev), dev, (uint32_t *)request); + + return (error); +} + +static int spigen_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, struct thread *td) { @@ -272,6 +294,12 @@ spigen_ioctl(struct cdev *cdev, u_long cmd, caddr_t da break; case SPIGENIOC_SET_SPI_MODE: error = spibus_set_mode(dev, *(uint32_t *)data); + break; + case SPIGENIOC_SBE: + error = spigen_sbe(cdev, (uint32_t *)data); + break; + case SPIGENIOC_SBPOL: + error = spigen_sbpol(cdev, (uint32_t *)data); break; default: error = ENOTTY; --- sys/spigenio.h.orig 2018-12-22 00:48:50.752200000 +0900 +++ sys/spigenio.h 2018-12-30 23:58:00.000000000 +0900 @@ -52,5 +52,7 @@ struct spigen_transfer_mmapped { #define SPIGENIOC_SET_CLOCK_SPEED _IOW(SPIGENIOC_BASE, 3, uint32_t) #define SPIGENIOC_GET_SPI_MODE _IOR(SPIGENIOC_BASE, 4, uint32_t) #define SPIGENIOC_SET_SPI_MODE _IOW(SPIGENIOC_BASE, 5, uint32_t) +#define SPIGENIOC_SBE _IOW(SPIGENIOC_BASE, 6, uint32_t) +#define SPIGENIOC_SBPOL _IOW(SPIGENIOC_BASE, 7, uint32_t) #endif /* !_SYS_SPIGENIO_H_ */ -- SAITOU Toshihide