Module Name:    src
Committed By:   msaitoh
Date:           Thu Jan  9 12:49:12 UTC 2020

Modified Files:
        src/sys/dev/pci: piixpm.c piixpmreg.h

Log Message:
 Acquire/release host semaphore to share SMBus between the host and
the embedded controller (IMC).

 Without this change, "shutdown -r" does power off and not boot on ECS HDC-I2.
This change fixes the problem.


To generate a diff of this commit:
cvs rdiff -u -r1.60 -r1.61 src/sys/dev/pci/piixpm.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/pci/piixpmreg.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/dev/pci/piixpm.c
diff -u src/sys/dev/pci/piixpm.c:1.60 src/sys/dev/pci/piixpm.c:1.61
--- src/sys/dev/pci/piixpm.c:1.60	Tue Dec 24 06:27:17 2019
+++ src/sys/dev/pci/piixpm.c	Thu Jan  9 12:49:12 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: piixpm.c,v 1.60 2019/12/24 06:27:17 thorpej Exp $ */
+/* $NetBSD: piixpm.c,v 1.61 2020/01/09 12:49:12 msaitoh Exp $ */
 /*	$OpenBSD: piixpm.c,v 1.39 2013/10/01 20:06:02 sf Exp $	*/
 
 /*
@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.60 2019/12/24 06:27:17 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.61 2020/01/09 12:49:12 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -71,6 +71,8 @@ __KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1
 
 #define PIIXPM_IS_FCHGRP(sc)	(PIIXPM_IS_HUDSON(sc) || PIIXPM_IS_KERNCZ(sc))
 
+#define PIIX_SB800_TIMEOUT 500
+
 struct piixpm_smbus {
 	int			sda;
 	struct			piixpm_softc *softc;
@@ -124,8 +126,8 @@ static bool	piixpm_resume(device_t, cons
 
 static int	piixpm_sb800_init(struct piixpm_softc *);
 static void	piixpm_csb5_reset(void *);
-static int	piixpm_i2c_acquire_bus(void *, int);
-static void	piixpm_i2c_release_bus(void *, int);
+static int	piixpm_i2c_sb800_acquire_bus(void *, int);
+static void	piixpm_i2c_sb800_release_bus(void *, int);
 static int	piixpm_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
     size_t, void *, size_t, int);
 
@@ -332,17 +334,24 @@ piixpm_rescan(device_t self, const char 
 	/* Attach I2C bus */
 
 	for (i = 0; i < sc->sc_numbusses; i++) {
+		struct i2c_controller *tag = &sc->sc_i2c_tags[i];
+
 		if (sc->sc_i2c_device[i])
 			continue;
 		sc->sc_busses[i].sda = i;
 		sc->sc_busses[i].softc = sc;
-		iic_tag_init(&sc->sc_i2c_tags[i]);
-		sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i];
-		sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus;
-		sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus;
-		sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec;
+		iic_tag_init(tag);
+		tag->ic_cookie = &sc->sc_busses[i];
+		if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_FCHGRP(sc)) {
+			tag->ic_acquire_bus = piixpm_i2c_sb800_acquire_bus;
+			tag->ic_release_bus = piixpm_i2c_sb800_release_bus;
+		} else {
+			tag->ic_acquire_bus = NULL;
+			tag->ic_release_bus = NULL;
+		}
+		tag->ic_exec = piixpm_i2c_exec;
 		memset(&iba, 0, sizeof(iba));
-		iba.iba_tag = &sc->sc_i2c_tags[i];
+		iba.iba_tag = tag;
 		sc->sc_i2c_device[i] = config_found_ia(self, ifattr, &iba,
 		    piixpm_iicbus_print);
 	}
@@ -485,17 +494,39 @@ piixpm_csb5_reset(void *arg)
 }
 
 static int
-piixpm_i2c_acquire_bus(void *cookie, int flags)
+piixpm_i2c_sb800_acquire_bus(void *cookie, int flags)
 {
 	struct piixpm_smbus *smbus = cookie;
 	struct piixpm_softc *sc = smbus->softc;
+	uint8_t sctl;
+	int i;
+
+	sctl = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC);
+	for (i = 0; i < PIIX_SB800_TIMEOUT; i++) {
+		/* Try to acquire the host semaphore */
+		sctl &= ~PIIX_SMB_SC_SEMMASK;
+		bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC,
+		    sctl | PIIX_SMB_SC_HOSTSEM);
+
+		sctl = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh,
+		    PIIX_SMB_SC);
+		if ((sctl & PIIX_SMB_SC_HOSTSEM) != 0)
+			break;
+
+		delay(1000);
+	}
+	if (i >= PIIX_SB800_TIMEOUT) {
+		device_printf(sc->sc_dev,
+		    "Failed to acquire the host semaphore\n");
+		return -1;
+	}
 
 	if (PIIXPM_IS_KERNCZ(sc)) {
 		bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 		    SB800_INDIRECTIO_INDEX, AMDFCH41_PM_PORT_INDEX);
 		bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 		    SB800_INDIRECTIO_DATA, smbus->sda << 3);
-	} else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) {
+	} else {
 		if (sc->sc_sb800_selen) {
 			bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 			    SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL);
@@ -519,10 +550,11 @@ piixpm_i2c_acquire_bus(void *cookie, int
 }
 
 static void
-piixpm_i2c_release_bus(void *cookie, int flags)
+piixpm_i2c_sb800_release_bus(void *cookie, int flags)
 {
 	struct piixpm_smbus *smbus = cookie;
 	struct piixpm_softc *sc = smbus->softc;
+	uint8_t sctl;
 
 	if (PIIXPM_IS_KERNCZ(sc)) {
 		bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
@@ -530,7 +562,7 @@ piixpm_i2c_release_bus(void *cookie, int
 		/* Set to port 0 */
 		bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 		    SB800_INDIRECTIO_DATA, 0);
-	} else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) {
+	} else {
 		if (sc->sc_sb800_selen) {
 			bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 			    SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL);
@@ -551,6 +583,12 @@ piixpm_i2c_release_bus(void *cookie, int
 			    SB800_INDIRECTIO_DATA, data);
 		}
 	}
+
+	/* Relase the host semaphore */
+	sctl = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC);
+	sctl &= ~PIIX_SMB_SC_SEMMASK;
+	bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC,
+	    sctl | PIIX_SMB_SC_CLRHOSTSEM);
 }
 
 static int

Index: src/sys/dev/pci/piixpmreg.h
diff -u src/sys/dev/pci/piixpmreg.h:1.10 src/sys/dev/pci/piixpmreg.h:1.11
--- src/sys/dev/pci/piixpmreg.h:1.10	Tue Dec 24 03:43:34 2019
+++ src/sys/dev/pci/piixpmreg.h	Thu Jan  9 12:49:12 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: piixpmreg.h,v 1.10 2019/12/24 03:43:34 msaitoh Exp $ */
+/* $NetBSD: piixpmreg.h,v 1.11 2020/01/09 12:49:12 msaitoh Exp $ */
 /*	$OpenBSD: piixreg.h,v 1.3 2006/01/03 22:39:03 grange Exp $	*/
 
 /*-
@@ -95,6 +95,11 @@
 #define PIIX_SMB_HBDB	0x07		/* host block data byte */
 #define PIIX_SMB_SC	0x08		/* slave control */
 #define PIIX_SMB_SC_ALERTEN	(1 << 3)	/* enable SMBALERT# */
+#define PIIX_SMB_SC_HOSTSEM	(1 << 4)	/* (W1S) HostSemaphore */
+#define PIIX_SMB_SC_CLRHOSTSEM	(1 << 5)	/* (W1C) ClrHostSemaphore */
+#define PIIX_SMB_SC_ECSEM	(1 << 6)	/* (W1S) EcSemaphore */
+#define PIIX_SMB_SC_CLRECSEM	(1 << 7)	/* (W1C) ClrEcSemaphore */
+#define PIIX_SMB_SC_SEMMASK	0xf0		/* Semaphore bits */
 
 /* Power management I/O registers */
 #define PIIX_PM_PMTMR	0x08		/* power management timer */

Reply via email to