Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Acquire/release host semaphore to share SMBus be...
details: https://anonhg.NetBSD.org/src/rev/1f34e39a4124
branches: trunk
changeset: 968270:1f34e39a4124
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Jan 09 12:49:12 2020 +0000
description:
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.
diffstat:
sys/dev/pci/piixpm.c | 66 ++++++++++++++++++++++++++++++++++++++----------
sys/dev/pci/piixpmreg.h | 7 ++++-
2 files changed, 58 insertions(+), 15 deletions(-)
diffs (167 lines):
diff -r 706fbe571a37 -r 1f34e39a4124 sys/dev/pci/piixpm.c
--- a/sys/dev/pci/piixpm.c Thu Jan 09 10:54:16 2020 +0000
+++ b/sys/dev/pci/piixpm.c Thu Jan 09 12:49:12 2020 +0000
@@ -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 @@
#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 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 @@
/* 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 @@
}
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 @@
}
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 @@
/* 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 @@
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
diff -r 706fbe571a37 -r 1f34e39a4124 sys/dev/pci/piixpmreg.h
--- a/sys/dev/pci/piixpmreg.h Thu Jan 09 10:54:16 2020 +0000
+++ b/sys/dev/pci/piixpmreg.h Thu Jan 09 12:49:12 2020 +0000
@@ -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 */
Home |
Main Index |
Thread Index |
Old Index