[coreboot-gerrit] Patch set updated for coreboot: ultra40m2: initialize hardware monitor and fan control

Jonathan A. Kollasch (jakllsch@kollasch.net) gerrit at coreboot.org
Fri Nov 6 16:12:54 CET 2015


Jonathan A. Kollasch (jakllsch at kollasch.net) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12309

-gerrit

commit 350e6f669b459d69654b6139d7ddf7431d89eb8e
Author: Jonathan A. Kollasch <jakllsch at kollasch.net>
Date:   Tue Nov 3 12:19:35 2015 -0600

    ultra40m2: initialize hardware monitor and fan control
    
    Change-Id: I3fbb897feb68d899e5dec075a09d0dd605eca5ce
    Signed-off-by: Jonathan A. Kollasch <jakllsch at kollasch.net>
---
 src/mainboard/sunw/ultra40m2/devicetree.cb |  12 +--
 src/mainboard/sunw/ultra40m2/mainboard.c   | 151 ++++++++++++++++++++++++++++-
 2 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/src/mainboard/sunw/ultra40m2/devicetree.cb b/src/mainboard/sunw/ultra40m2/devicetree.cb
index 9928d45..9982459 100644
--- a/src/mainboard/sunw/ultra40m2/devicetree.cb
+++ b/src/mainboard/sunw/ultra40m2/devicetree.cb
@@ -75,12 +75,12 @@ chip northbridge/amd/amdk8/root_complex		# Root complex
             #chip drivers/generic/generic	# PCA9556 GPIO on HDD backplanes (address conflict!)
             #  device i2c 18 on end
             #end
-            #chip drivers/generic/generic	# EMC6D103 HWM (for CPUs)
-            #  device i2c 2d on end
-            #end
-            #chip drivers/generic/generic	# DME1737 HWM
-            #  device i2c 2e on end
-            #end
+            chip drivers/generic/generic	# EMC6D103 HWM (for CPUs)
+              device i2c 2d on end
+            end
+            chip drivers/generic/generic	# DME1737 HWM
+              device i2c 2e on end
+            end
             #chip drivers/generic/generic	# HDD 4-7 backplane FRU 24C64 EEPROM
             #  device i2c 51 on end
             #end
diff --git a/src/mainboard/sunw/ultra40m2/mainboard.c b/src/mainboard/sunw/ultra40m2/mainboard.c
index 1f26995..3e2bbf0 100644
--- a/src/mainboard/sunw/ultra40m2/mainboard.c
+++ b/src/mainboard/sunw/ultra40m2/mainboard.c
@@ -15,15 +15,160 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/io.h>
 #include <console/console.h>
 #include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
+#include <device/pnp_def.h>
+#include <device/smbus.h>
+#include <stdlib.h>
+#include <superio/smsc/dme1737/dme1737.h>
 
+static void emc6d103_init(void)
+{
+	size_t i;
+	int reg;
+
+	static const struct { uint8_t idx; uint8_t msk; uint8_t set; } script[] = {
+		{ 0x7f, 0x7f, 0x80 }, // INIT
+		{ 0x4f, 0x00, 0x64 }, // Diode 1 High 100°C
+		{ 0x53, 0x00, 0x64 }, // Diode 2 High 100°C (Sun firmware didn't set this)
+		{ 0x54, 0x00, 0x30 }, // Tach1 Minimum LSB
+		{ 0x55, 0x00, 0x2a }, // Tach1 Minimum MSB
+		{ 0x56, 0x00, 0x30 }, // Tach2 Minimum LSB
+		{ 0x57, 0x00, 0x2a }, // Tach2 Minimum MSB
+		{ 0x5c, 0x00, 0x02 }, // PWM 1 Config
+		{ 0x5d, 0x00, 0x42 }, // PWM 2 Config
+		{ 0x5f, 0x00, 0x8a }, // Zone 1 range, Fan 1 freq
+		{ 0x60, 0x00, 0xca }, // Zone 2 range, Fan 2 freq
+		{ 0x61, 0x00, 0x8a }, // Zone 3 range, Fan 3 freq
+		{ 0x62, 0x00, 0x67 }, // Min/Off, PWM 1 ramp rate
+		{ 0x63, 0x00, 0x70 }, // PWM 2, PWM 3 ramp rate
+		{ 0x64, 0x00, 0x59 }, // PWM1 Minimum Duty Cycle
+		{ 0x65, 0x00, 0x59 }, // PWM2 Minimum Duty Cycle
+		{ 0x67, 0x00, 0x47 }, // Zone 1 Low Temp Limit
+		{ 0x69, 0x00, 0x47 }, // Zone 3 Low Temp Limit
+		{ 0x80, 0x00, 0x07 }, // Interrupt Enable 2
+		{ 0x40, 0xfe, 0x01 }, // START
+	};
+
+	struct device * const dev = dev_find_slot_on_smbus(2, 0x2d);
+	if (dev == NULL)
+		printk(BIOS_WARNING, "EMC6D103 not found\n");
+
+	printk(BIOS_SPEW, "%s EMC6D103 id: %x %x\n", __func__, smbus_read_byte(dev, 0x3e), smbus_read_byte(dev, 0x3f));
+
+	for (i = 0; i < ARRAY_SIZE(script); i++) {
+		reg = smbus_read_byte(dev, script[i].idx);
+		if (reg < 0)
+			goto fail;
+		reg &= script[i].msk;
+		reg |= script[i].set;
+		reg = smbus_write_byte(dev, script[i].idx, reg & 0xff);
+		if (reg < 0)
+			goto fail;
+	}
+
+	return;
+
+fail:
+	printk(BIOS_WARNING, "failed to initialize EMC6D103\n");
+}
+
+/* set up DME1737 runtime registers for FAN/PWM 5/6 */
+static void dme1737_runtime_init(void)
+{
+	size_t i;
+	uint8_t reg;
+
+	static const struct { uint8_t idx; uint8_t msk; uint8_t set; } rttab[] = {
+		{ 0x43, 0xf3, 0x08 },
+		{ 0x44, 0xf0, 0x08 },
+		{ 0x45, 0xf3, 0x08 },
+		{ 0x46, 0xf0, 0x08 },
+	};
+
+	/* find DME1737 runtime device (LDN 10) */
+	struct device * const dev = dev_find_slot_pnp(0x2e, DME1737_RT);
+	if (dev == NULL)
+		return;
+
+	struct resource * const res = find_resource(dev, PNP_IDX_IO0);
+	if (res == NULL)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(rttab); i++) {
+		reg = inb(res->base + rttab[i].idx);
+		reg &= rttab[i].msk;
+		reg |= rttab[i].set;
+		outb(reg, res->base + rttab[i].idx);
+	}
+}
+
+static void dme1737_hwm_init(void)
+{
+	size_t i;
+	int reg;
+
+	static const struct { uint8_t idx; uint8_t msk; uint8_t set; } script[] = {
+		//{ 0x7f, 0x7f, 0x80 }, // INIT
+		{ 0x4f, 0x00, 0x32 }, // High
+		{ 0x54, 0x00, 0x30 }, // Tach0 Minimum LSB
+		{ 0x55, 0x00, 0x2a }, // Tach0 Minimum MSB
+		{ 0x56, 0x00, 0x30 }, // Tach1 Minimum LSB
+		{ 0x57, 0x00, 0x2a }, // Tach1 Minimum MSB
+		{ 0x5a, 0x00, 0x30 }, // Tach3 Minimum LSB
+		{ 0x5b, 0x00, 0x2a }, // Tach3 Minimum MSB
+		{ 0x5d, 0x00, 0x07 }, // PWM 1 Config: Zone 0
+		{ 0x5f, 0x0f, 0x50 }, // Zone 0 range, PWM freq
+		{ 0x62, 0x00, 0x67 }, // Ramp Rate
+		{ 0x63, 0x00, 0x80 }, // Ramp Rate
+		{ 0x65, 0x00, 0x0d }, // PWM 1 Minimum
+		{ 0x67, 0x00, 0x23 }, // Zone 0 Low
+		{ 0x6a, 0x00, 0x32 }, // Zone 0 High
+		{ 0x6c, 0x00, 0x5a }, // Zone 2 Abs
+		{ 0x80, 0x00, 0x17 }, // Interrupt Enable 2?
+		{ 0xa5, 0x00, 0x40 }, // PMW 4: 25% duty
+		{ 0xa6, 0x00, 0x40 }, // PWM 5: 25% duty
+		{ 0x40, 0xfe, 0x01 }, // START
+	};
+
+	struct device * const dev = dev_find_slot_on_smbus(2, 0x2e);
+	if (dev == NULL) {
+		printk(BIOS_INFO, "SMBus DME1737 not found\n");
+		return;
+	}
+
+	printk(BIOS_SPEW, "%s DME1737 id: %x %x\n", __func__, smbus_read_byte(dev, 0x3e), smbus_read_byte(dev, 0x3f));
+
+	for (i = 0; i < ARRAY_SIZE(script); i++) {
+		reg = smbus_read_byte(dev, script[i].idx);
+		if (reg < 0)
+			goto fail;
+		reg &= script[i].msk;
+		reg |= script[i].set;
+		reg = smbus_write_byte(dev, script[i].idx, reg & 0xff);
+		if (reg < 0)
+			goto fail;
+	}
+
+	return;
+
+fail:
+	printk(BIOS_WARNING, "failed to initialize EMC6D103\n");
+}
+
+static void mainboard_init(device_t dev)
+{
+	emc6d103_init();
+	dme1737_runtime_init();
+	dme1737_hwm_init();
+
+	printk(BIOS_DEBUG, "%s done\n", __func__);
+}
 
 static void mainboard_enable(device_t dev)
 {
+	dev->ops->init = mainboard_init;
 }
 
 struct chip_operations mainboard_ops = {



More information about the coreboot-gerrit mailing list