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);

Reply via email to