Module Name: src Committed By: snj Date: Tue Nov 25 07:49:22 UTC 2014
Modified Files: src/sys/arch/arm/allwinner [netbsd-7]: awin_reg.h awin_twi.c src/sys/arch/evbarm/conf [netbsd-7]: HUMMINGBIRD_A31 src/sys/dev/i2c [netbsd-7]: gttwsi_core.c gttwsivar.h Log Message: Pull up following revision(s) (requested by jmcneill in ticket #257): sys/arch/arm/allwinner/awin_twi.c: revision 1.5 sys/arch/arm/allwinner/awin_reg.h: revision 1.53 sys/arch/evbarm/conf/HUMMINGBIRD_A31: revision 1.20 sys/dev/i2c/gttwsi_core.c: revision 1.2 sys/dev/i2c/gttwsivar.h: revision 1.2 On Allwinner A31 you need to set the CONTROL_IFLG bit to clear it. Add a "iflg-rwc" property to enable this behaviour. -- Don't assume that U-Boot has enabled the TWI clock. Also, for A31, set the "iflg-rwc" device property for gttwsi. -- The SoC RTC works on this board but does not seem to be hooked up to the battery. Thankfully, there is a PCF8563 attached to TWI2 at address 51h, so use that instead. To generate a diff of this commit: cvs rdiff -u -r1.14.2.5 -r1.14.2.6 src/sys/arch/arm/allwinner/awin_reg.h cvs rdiff -u -r1.3.10.1 -r1.3.10.2 src/sys/arch/arm/allwinner/awin_twi.c cvs rdiff -u -r1.19.2.4 -r1.19.2.5 src/sys/arch/evbarm/conf/HUMMINGBIRD_A31 cvs rdiff -u -r1.1 -r1.1.10.1 src/sys/dev/i2c/gttwsi_core.c \ src/sys/dev/i2c/gttwsivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/allwinner/awin_reg.h diff -u src/sys/arch/arm/allwinner/awin_reg.h:1.14.2.5 src/sys/arch/arm/allwinner/awin_reg.h:1.14.2.6 --- src/sys/arch/arm/allwinner/awin_reg.h:1.14.2.5 Sun Nov 16 10:33:57 2014 +++ src/sys/arch/arm/allwinner/awin_reg.h Tue Nov 25 07:49:22 2014 @@ -2037,6 +2037,7 @@ struct awin_mmc_idma_descriptor { #define AWIN_A31_AHB_RESET1_REG 0x02C4 #define AWIN_A31_AHB_RESET2_REG 0x02C8 #define AWIN_A31_APB1_RESET_REG 0x02D0 +#define AWIN_A31_APB2_RESET_REG 0x02D8 #define AWIN_A31_PRCM_APB0_GATING_CIR __BIT(1) @@ -2142,6 +2143,11 @@ struct awin_mmc_idma_descriptor { #define AWIN_A31_APB1_RESET_DIGITAL_MIC_RST __BIT(4) #define AWIN_A31_APB1_RESET_CODEC_RST __BIT(0) +#define AWIN_A31_APB2_RESET_TWI3_RST __BIT(3) +#define AWIN_A31_APB2_RESET_TWI2_RST __BIT(2) +#define AWIN_A31_APB2_RESET_TWI1_RST __BIT(1) +#define AWIN_A31_APB2_RESET_TWI0_RST __BIT(0) + #define AWIN_A31_WDOG1_IRQ_EN_REG 0x00A0 #define AWIN_A31_WDOG1_IRQ_STA_REG 0x00A4 #define AWIN_A31_WDOG1_CTRL_REG 0x00B0 Index: src/sys/arch/arm/allwinner/awin_twi.c diff -u src/sys/arch/arm/allwinner/awin_twi.c:1.3.10.1 src/sys/arch/arm/allwinner/awin_twi.c:1.3.10.2 --- src/sys/arch/arm/allwinner/awin_twi.c:1.3.10.1 Sun Nov 9 14:42:33 2014 +++ src/sys/arch/arm/allwinner/awin_twi.c Tue Nov 25 07:49:22 2014 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_twi.c,v 1.3.10.1 2014/11/09 14:42:33 martin Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_twi.c,v 1.3.10.2 2014/11/25 07:49:22 snj Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -45,6 +45,10 @@ __KERNEL_RCSID(1, "$NetBSD: awin_twi.c,v #include <arm/allwinner/awin_reg.h> #include <arm/allwinner/awin_var.h> +#define TWI_CCR_REG 0x14 +#define TWI_CCR_CLK_M __BITS(6,3) +#define TWI_CCR_CLK_N __BITS(2,0) + static int awin_twi_match(device_t, cfdata_t, void *); static void awin_twi_attach(device_t, device_t, void *); @@ -109,12 +113,14 @@ awin_twi_attach(device_t parent, device_ struct awin_twi_softc * const asc = device_private(self); struct awinio_attach_args * const aio = aux; const struct awin_locators * const loc = &aio->aio_loc; + prop_dictionary_t cfg = device_properties(self); bus_space_handle_t bsh; + uint32_t ccr; awin_twi_ports |= __BIT(loc->loc_port); /* - * Acquite the PIO pins needed for the TWI port. + * Acquire the PIO pins needed for the TWI port. */ if (awin_chip_id() == AWIN_CHIP_ID_A31) { awin_gpio_pinset_acquire(&awin_twi_pinsets_a31[loc->loc_port]); @@ -123,12 +129,38 @@ awin_twi_attach(device_t parent, device_ } /* + * Clock gating, soft reset + */ + awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, + AWIN_APB1_GATING_REG, AWIN_APB_GATING1_TWI0 << loc->loc_port, 0); + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh, + AWIN_A31_APB2_RESET_REG, + AWIN_A31_APB2_RESET_TWI0_RST << loc->loc_port, 0); + } + + /* * Get a bus space handle for this TWI port. */ bus_space_subregion(aio->aio_core_bst, aio->aio_core_bsh, loc->loc_offset, loc->loc_size, &bsh); /* + * A31 specific quirk + */ + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + prop_dictionary_set_bool(cfg, "iflg-rwc", true); + } + + /* + * 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 + */ + ccr = __SHIFTIN(11, TWI_CCR_CLK_M) | __SHIFTIN(2, TWI_CCR_CLK_N); + bus_space_write_4(aio->aio_core_bst, bsh, TWI_CCR_REG, ccr); + + /* * Do the MI attach */ gttwsi_attach_subr(self, aio->aio_core_bst, bsh); Index: src/sys/arch/evbarm/conf/HUMMINGBIRD_A31 diff -u src/sys/arch/evbarm/conf/HUMMINGBIRD_A31:1.19.2.4 src/sys/arch/evbarm/conf/HUMMINGBIRD_A31:1.19.2.5 --- src/sys/arch/evbarm/conf/HUMMINGBIRD_A31:1.19.2.4 Fri Nov 14 18:11:22 2014 +++ src/sys/arch/evbarm/conf/HUMMINGBIRD_A31 Tue Nov 25 07:49:22 2014 @@ -1,4 +1,4 @@ -# $NetBSD: HUMMINGBIRD_A31,v 1.19.2.4 2014/11/14 18:11:22 snj Exp $ +# $NetBSD: HUMMINGBIRD_A31,v 1.19.2.5 2014/11/25 07:49:22 snj Exp $ # # HUMMINGBIRD_A31 - Merrii Hummingbird A31 # @@ -206,10 +206,13 @@ awingpio0 at awinio0 gpio* at awingpio? -# I2C Controller -awiniic0 at awinio? port 0 -#awiniic* at awinio? port ? -iic0 at awiniic0 +# I2C Controllers +#awiniic0 at awinio? port 0 +#iic0 at awiniic0 + +awiniic2 at awinio? port 2 +iic2 at awiniic2 +pcf8563rtc0 at iic2 addr 0x51 # PCF8563 RTC # P2WI awinp2wi0 at awinio0 @@ -227,8 +230,8 @@ cir0 at awinir0 # Watchdog timers awinwdt* at awinio? -# RTC -awinrtc* at awinio? +# RTC (not battery backed on this board; use PCF8563 instead) +#awinrtc* at awinio? # onboard audio codec awinac0 at awinio0 Index: src/sys/dev/i2c/gttwsi_core.c diff -u src/sys/dev/i2c/gttwsi_core.c:1.1 src/sys/dev/i2c/gttwsi_core.c:1.1.10.1 --- src/sys/dev/i2c/gttwsi_core.c:1.1 Fri Sep 6 00:56:12 2013 +++ src/sys/dev/i2c/gttwsi_core.c Tue Nov 25 07:49:22 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: gttwsi_core.c,v 1.1 2013/09/06 00:56:12 matt Exp $ */ +/* $NetBSD: gttwsi_core.c,v 1.1.10.1 2014/11/25 07:49:22 snj Exp $ */ /* * Copyright (c) 2008 Eiji Kawauchi. * All rights reserved. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gttwsi_core.c,v 1.1 2013/09/06 00:56:12 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gttwsi_core.c,v 1.1.10.1 2014/11/25 07:49:22 snj Exp $"); #include "locators.h" #include <sys/param.h> @@ -124,6 +124,7 @@ void gttwsi_attach_subr(device_t self, bus_space_tag_t iot, bus_space_handle_t ioh) { struct gttwsi_softc * const sc = device_private(self); + prop_dictionary_t cfg = device_properties(self); aprint_naive("\n"); aprint_normal(": Marvell TWSI controller\n"); @@ -136,6 +137,8 @@ gttwsi_attach_subr(device_t self, bus_sp mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_BIO); cv_init(&sc->sc_cv, device_xname(self)); + prop_dictionary_get_bool(cfg, "iflg-rwc", &sc->sc_iflg_rwc); + sc->sc_started = false; sc->sc_i2c.ic_cookie = sc; sc->sc_i2c.ic_acquire_bus = gttwsi_acquire_bus; @@ -223,11 +226,15 @@ gttwsi_send_stop(void *v, int flags) { struct gttwsi_softc *sc = v; int retry = TWSI_RETRY_COUNT; + uint32_t control; sc->sc_started = false; /* Interrupt is not generated for STAT_NRS. */ - gttwsi_write_4(sc, TWSI_CONTROL, CONTROL_STOP | CONTROL_TWSIEN); + control = CONTROL_STOP | CONTROL_TWSIEN; + if (sc->sc_iflg_rwc) + control |= CONTROL_IFLG; + gttwsi_write_4(sc, TWSI_CONTROL, control); while (retry > 0) { if (gttwsi_read_4(sc, TWSI_STATUS) == STAT_NRS) return 0; @@ -324,6 +331,8 @@ gttwsi_wait(struct gttwsi_softc *sc, uin DELAY(5); if (!(flags & I2C_F_POLL)) control |= CONTROL_INTEN; + if (sc->sc_iflg_rwc) + control |= CONTROL_IFLG; gttwsi_write_4(sc, TWSI_CONTROL, control | CONTROL_TWSIEN); timo = 0; Index: src/sys/dev/i2c/gttwsivar.h diff -u src/sys/dev/i2c/gttwsivar.h:1.1 src/sys/dev/i2c/gttwsivar.h:1.1.10.1 --- src/sys/dev/i2c/gttwsivar.h:1.1 Fri Sep 6 00:56:12 2013 +++ src/sys/dev/i2c/gttwsivar.h Tue Nov 25 07:49:22 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: gttwsivar.h,v 1.1 2013/09/06 00:56:12 matt Exp $ */ +/* $NetBSD: gttwsivar.h,v 1.1.10.1 2014/11/25 07:49:22 snj Exp $ */ /* * Copyright (c) 2008 Eiji Kawauchi. * All rights reserved. @@ -87,6 +87,8 @@ struct gttwsi_softc { kmutex_t sc_buslock; kmutex_t sc_mtx; kcondvar_t sc_cv; + + bool sc_iflg_rwc; }; void gttwsi_attach_subr(device_t, bus_space_tag_t, bus_space_handle_t);