Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/sunxi Set twi clock based on parent clock, and ...
details: https://anonhg.NetBSD.org/src/rev/0e04559e4f90
branches: trunk
changeset: 357874:0e04559e4f90
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Thu Nov 30 20:41:21 2017 +0000
description:
Set twi clock based on parent clock, and fix register remapping for writes.
diffstat:
sys/arch/arm/sunxi/sunxi_twi.c | 88 ++++++++++++++++++++++++++++-------------
1 files changed, 60 insertions(+), 28 deletions(-)
diffs (138 lines):
diff -r 853b79123b2a -r 0e04559e4f90 sys/arch/arm/sunxi/sunxi_twi.c
--- a/sys/arch/arm/sunxi/sunxi_twi.c Thu Nov 30 20:25:54 2017 +0000
+++ b/sys/arch/arm/sunxi/sunxi_twi.c Thu Nov 30 20:41:21 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_twi.c,v 1.6 2017/10/29 15:00:00 jmcneill Exp $ */
+/* $NetBSD: sunxi_twi.c,v 1.7 2017/11/30 20:41:21 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -33,7 +33,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_twi.c,v 1.6 2017/10/29 15:00:00 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_twi.c,v 1.7 2017/11/30 20:41:21 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -52,14 +52,22 @@
#define TWI_CCR_CLK_M __BITS(6,3)
#define TWI_CCR_CLK_N __BITS(2,0)
-static uint8_t sunxi_twi_regmap[] = {
- [TWSI_SLAVEADDR] = 0x00,
- [TWSI_EXTEND_SLAVEADDR] = 0x04,
- [TWSI_DATA] = 0x08,
- [TWSI_CONTROL] = 0x0c,
- [TWSI_STATUS] = 0x10,
- [TWSI_BAUDRATE] = 0x14,
- [TWSI_SOFTRESET] = 0x18,
+static uint8_t sunxi_twi_regmap_rd[] = {
+ [TWSI_SLAVEADDR/4] = 0x00,
+ [TWSI_EXTEND_SLAVEADDR/4] = 0x04,
+ [TWSI_DATA/4] = 0x08,
+ [TWSI_CONTROL/4] = 0x0c,
+ [TWSI_STATUS/4] = 0x10,
+ [TWSI_SOFTRESET/4] = 0x18,
+};
+
+static uint8_t sunxi_twi_regmap_wr[] = {
+ [TWSI_SLAVEADDR/4] = 0x00,
+ [TWSI_EXTEND_SLAVEADDR/4] = 0x04,
+ [TWSI_DATA/4] = 0x08,
+ [TWSI_CONTROL/4] = 0x0c,
+ [TWSI_BAUDRATE/4] = 0x14,
+ [TWSI_SOFTRESET/4] = 0x18,
};
static int sunxi_twi_match(device_t, cfdata_t, void *);
@@ -101,13 +109,42 @@
static uint32_t
sunxi_twi_reg_read(struct gttwsi_softc *sc, uint32_t reg)
{
- return bus_space_read_4(sc->sc_bust, sc->sc_bush, sunxi_twi_regmap[reg]);
+ return bus_space_read_4(sc->sc_bust, sc->sc_bush, sunxi_twi_regmap_rd[reg/4]);
}
static void
sunxi_twi_reg_write(struct gttwsi_softc *sc, uint32_t reg, uint32_t val)
{
- bus_space_write_4(sc->sc_bust, sc->sc_bush, sunxi_twi_regmap[reg], val);
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, sunxi_twi_regmap_wr[reg/4], val);
+}
+
+static u_int
+sunxi_twi_calc_rate(u_int parent_rate, u_int n, u_int m)
+{
+ return parent_rate / (10 * (m + 1) * (1 << n));
+}
+
+static void
+sunxi_twi_set_clock(struct gttwsi_softc *sc, u_int parent_rate, u_int rate)
+{
+ uint32_t baud;
+ u_int n, m, best_rate;
+
+ baud = sunxi_twi_reg_read(sc, TWSI_BAUDRATE);
+
+ for (best_rate = 0, n = 0; n < 8; n++) {
+ for (m = 0; m < 16; m++) {
+ const u_int tmp_rate = sunxi_twi_calc_rate(parent_rate, n, m);
+ if (tmp_rate <= rate && tmp_rate > best_rate) {
+ best_rate = tmp_rate;
+ baud = __SHIFTIN(n, TWI_CCR_CLK_N) |
+ __SHIFTIN(m, TWI_CCR_CLK_M);
+ }
+ }
+ }
+
+ sunxi_twi_reg_write(sc, TWSI_BAUDRATE, baud);
+ delay(10000);
}
static int
@@ -152,11 +189,11 @@
return;
}
- if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL)
- if (clk_enable(clk) != 0) {
- aprint_error(": couldn't enable clock\n");
- return;
- }
+ clk = fdtbus_clock_get_index(phandle, 0);
+ if (clk == NULL || clk_enable(clk) != 0) {
+ aprint_error(": couldn't enable clock\n");
+ return;
+ }
if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL)
if (fdtbus_reset_deassert(rst) != 0) {
aprint_error(": couldn't de-assert reset\n");
@@ -167,20 +204,15 @@
prop_dictionary_set_bool(device_properties(self), "iflg-rwc",
conf->iflg_rwc);
- /*
- * 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
- */
- const u_int m = 11, n = 2;
- const uint32_t ccr = __SHIFTIN(n, TWI_CCR_CLK_N) |
- __SHIFTIN(m, TWI_CCR_CLK_M);
- bus_space_write_4(bst, bsh, TWI_CCR_REG, ccr);
-
+ /* Attach gttwsi core */
sc->sc_reg_read = sunxi_twi_reg_read;
sc->sc_reg_write = sunxi_twi_reg_write;
+ gttwsi_attach_subr(self, bst, bsh);
- gttwsi_attach_subr(self, bst, bsh);
+ /*
+ * Set clock rate to 100kHz.
+ */
+ sunxi_twi_set_clock(sc, clk_get_rate(clk), 100000);
ih = fdtbus_intr_establish(phandle, 0, IPL_VM, 0, gttwsi_intr, sc);
if (ih == NULL) {
Home |
Main Index |
Thread Index |
Old Index