From owner-svn-src-head@freebsd.org Thu May 17 14:51:23 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 25849EAA9F3; Thu, 17 May 2018 14:51:23 +0000 (UTC) (envelope-from manu@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 C6CC183340; Thu, 17 May 2018 14:51:22 +0000 (UTC) (envelope-from manu@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 A8A5B2A66; Thu, 17 May 2018 14:51:22 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w4HEpMlW075779; Thu, 17 May 2018 14:51:22 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w4HEpMOD075777; Thu, 17 May 2018 14:51:22 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201805171451.w4HEpMOD075777@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Thu, 17 May 2018 14:51:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333716 - head/sys/arm/allwinner X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: head/sys/arm/allwinner X-SVN-Commit-Revision: 333716 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.26 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: Thu, 17 May 2018 14:51:23 -0000 Author: manu Date: Thu May 17 14:51:22 2018 New Revision: 333716 URL: https://svnweb.freebsd.org/changeset/base/333716 Log: aw_spi: Fix some silly clock mistake The module uses the mod clock and not the ahb one. We need to set the mod clock to twice the speed requested as the smallest divider in the controller is 2. The clock test function weren't calculating the register value best on the best div but on the max one. The cdr2 test function was using the cdr1 formula. Pointy Hat: manu Modified: head/sys/arm/allwinner/aw_spi.c Modified: head/sys/arm/allwinner/aw_spi.c ============================================================================== --- head/sys/arm/allwinner/aw_spi.c Thu May 17 14:38:58 2018 (r333715) +++ head/sys/arm/allwinner/aw_spi.c Thu May 17 14:51:22 2018 (r333716) @@ -143,7 +143,7 @@ struct aw_spi_softc { struct mtx mtx; clk_t clk_ahb; clk_t clk_mod; - uint64_t ahb_freq; + uint64_t mod_freq; hwreset_t rst_ahb; void * intrhand; int transfer; @@ -238,8 +238,6 @@ aw_spi_attach(device_t dev) goto fail; } - clk_get_freq(sc->clk_ahb, &sc->ahb_freq); - sc->spibus = device_add_child(dev, "spibus", -1); return (0); @@ -329,33 +327,33 @@ aw_spi_clock_test_cdr1(struct aw_spi_softc *sc, uint64 max = AW_SPI_CCR_CDR1_MASK >> AW_SPI_CCR_CDR1_SHIFT; for (i = 0; i < max; i++) { - cur = sc->ahb_freq / (1 << i); + cur = sc->mod_freq / (1 << i); if ((clock - cur) < (clock - best)) { best = cur; best_div = i; } } - *ccr = (i << AW_SPI_CCR_CDR1_SHIFT); + *ccr = (best_div << AW_SPI_CCR_CDR1_SHIFT); return (best); } static uint64_t -aw_spi_clock_test_cdr2(struct aw_spi_softc *sc, uint32_t clock, uint32_t *ccr) +aw_spi_clock_test_cdr2(struct aw_spi_softc *sc, uint64_t clock, uint32_t *ccr) { uint64_t cur, best = 0; int i, max, best_div; max = ((AW_SPI_CCR_CDR2_MASK) >> AW_SPI_CCR_CDR2_SHIFT); for (i = 0; i < max; i++) { - cur = sc->ahb_freq / (1 << i); + cur = sc->mod_freq / (2 * i + 1); if ((clock - cur) < (clock - best)) { best = cur; best_div = i; } } - *ccr = AW_SPI_CCR_DRS | (i << AW_SPI_CCR_CDR2_SHIFT); + *ccr = AW_SPI_CCR_DRS | (best_div << AW_SPI_CCR_CDR2_SHIFT); return (best); } @@ -531,6 +529,9 @@ aw_spi_transfer(device_t dev, device_t child, struct s spibus_get_clock(child, &clock); spibus_get_mode(child, &mode); + /* The minimum divider is 2 so set the clock at twice the needed speed */ + clk_set_freq(sc->clk_mod, 2 * clock, CLK_SET_ROUND_DOWN); + clk_get_freq(sc->clk_mod, &sc->mod_freq); if (cs >= AW_SPI_MAX_CS) { device_printf(dev, "Invalid cs %d\n", cs); return (EINVAL);