From 2284a7be30b2055d7cc8d1339227577835d2704a Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 6 Jan 2018 11:23:14 +0000 Subject: [PATCH] Set the proper bus clock rate based on the "clock-frequency" property and the rate of the parent clock. If the "clock-frequency" property isn't present, use the default standard mode clock of 100kHz. --- sys/dev/fdt/sxitwi.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/sys/dev/fdt/sxitwi.c b/sys/dev/fdt/sxitwi.c index 98eae994fee..e97234896e3 100644 --- a/sys/dev/fdt/sxitwi.c +++ b/sys/dev/fdt/sxitwi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxitwi.c,v 1.6 2018/01/05 12:46:13 kettenis Exp $ */ +/* $OpenBSD: sxitwi.c,v 1.7 2018/01/06 11:23:14 kettenis Exp $ */ /* $NetBSD: gttwsi_core.c,v 1.2 2014/11/23 13:37:27 jmcneill Exp $ */ /* * Copyright (c) 2008 Eiji Kawauchi. @@ -180,12 +180,35 @@ sxitwi_attach(struct device *parent, struct device *self, void *aux) struct sxitwi_softc *sc = (struct sxitwi_softc *)self; struct fdt_attach_args *faa = aux; struct i2cbus_attach_args iba; + uint32_t freq, parent_freq; + uint32_t m, n; if (faa->fa_nreg < 1) { printf(": no registers\n"); return; } + /* + * Calculate clock dividers up front such that we can bail out + * early if the desired clock rate can't be obtained. Make + * sure the bus clock rate is never above the desired rate. + */ + parent_freq = clock_get_frequency(faa->fa_node, NULL); + freq = OF_getpropint(faa->fa_node, "clock-frequency", 100000); + if (parent_freq == 0) { + printf(": unknown clock frequency\n"); + return; + } + n = 0, m = 0; + while ((freq * (1 << n) * 16 * 10) < parent_freq) + n++; + while ((freq * (1 << n) * (m + 1) * 10) < parent_freq) + m++; + if (n > 8 || m > 16) { + printf(": clock frequency too high\n"); + return; + } + sc->sc_node = faa->fa_node; sc->sc_iot = faa->fa_iot; @@ -222,12 +245,8 @@ sxitwi_attach(struct device *parent, struct device *self, void *aux) clock_enable(faa->fa_node, NULL); reset_deassert_all(faa->fa_node); - /* - * Set clock rate to 100kHz. From the datasheet: - * For 100Khz standard speed 2Wire, CLK_N=2, CLK_M=11 - * F0=48M/2^2=12Mhz, F1=F0/(10*(11+1)) = 0.1Mhz - */ - sxitwi_write_4(sc, TWI_CCR_REG, (11 << 3) | (2 << 0)); + /* Set clock rate. */ + sxitwi_write_4(sc, TWI_CCR_REG, (m << 3) | (n << 0)); /* Put the controller into Soft Reset. */ sxitwi_write_4(sc, TWSI_SOFTRESET, SOFTRESET_VAL); -- 2.20.1