[coreboot-gerrit] Patch set updated for coreboot: 358fd58 lynxpoint: me: Support ICC clock enables message

Patrick Georgi (patrick@georgi-clan.de) gerrit at coreboot.org
Fri Dec 20 23:32:32 CET 2013


Patrick Georgi (patrick at georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4450

-gerrit

commit 358fd586a5ff4a8037548da6689055b5fec3a60a
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Thu Aug 8 15:31:51 2013 -0700

    lynxpoint: me: Support ICC clock enables message
    
    This message allows unused clocks to be disabled based on a
    devicetree setting in each mainboard.
    
    Change-Id: Ib1988cab3748490cf24028752562c64ccbce2054
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://gerrit.chromium.org/gerrit/65250
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/southbridge/intel/lynxpoint/chip.h   |  7 +++++
 src/southbridge/intel/lynxpoint/me.h     | 18 +++++++++++
 src/southbridge/intel/lynxpoint/me_9.x.c | 54 +++++++++++++++++++++++++++++++-
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/src/southbridge/intel/lynxpoint/chip.h b/src/southbridge/intel/lynxpoint/chip.h
index 70f3e63..a0e2232 100644
--- a/src/southbridge/intel/lynxpoint/chip.h
+++ b/src/southbridge/intel/lynxpoint/chip.h
@@ -92,6 +92,13 @@ struct southbridge_intel_lynxpoint_config {
 	/* I2C voltage select: 0=3.3V 1=1.8V */
 	uint8_t sio_i2c0_voltage;
 	uint8_t sio_i2c1_voltage;
+
+	/*
+	 * Clock Disable Map:
+	 * [21:16] = CLKOUT_PCIE# 5-0
+	 *    [24] = CLKOUT_ITPXDP
+	 */
+	uint32_t icc_clock_disable;
 };
 
 extern struct chip_operations southbridge_intel_lynxpoint_ops;
diff --git a/src/southbridge/intel/lynxpoint/me.h b/src/southbridge/intel/lynxpoint/me.h
index d919107..a72778b 100644
--- a/src/southbridge/intel/lynxpoint/me.h
+++ b/src/southbridge/intel/lynxpoint/me.h
@@ -286,6 +286,24 @@ struct me_fw_version {
 	u16 recovery_hot_fix;
 } __attribute__ ((packed));
 
+/* ICC Messages */
+#define ICC_SET_CLOCK_ENABLES		0x3
+#define ICC_API_VERSION_LYNXPOINT	0x00030000
+
+struct icc_header {
+	u32 api_version;
+	u32 icc_command;
+	u32 icc_status;
+	u32 length;
+	u32 reserved;
+} __attribute__ ((packed));
+
+struct icc_clock_enables_msg {
+	u32 clock_enables;
+	u32 clock_mask;
+	u32 no_response: 1;
+	u32 reserved: 31;
+} __attribute__ ((packed));
 
 #define HECI_EOP_STATUS_SUCCESS       0x0
 #define HECI_EOP_PERFORM_GLOBAL_RESET 0x1
diff --git a/src/southbridge/intel/lynxpoint/me_9.x.c b/src/southbridge/intel/lynxpoint/me_9.x.c
index d1a692c..e01316f 100644
--- a/src/southbridge/intel/lynxpoint/me_9.x.c
+++ b/src/southbridge/intel/lynxpoint/me_9.x.c
@@ -412,6 +412,30 @@ static inline int mei_sendrecv_mkhi(struct mkhi_header *mkhi,
 	return 0;
 }
 
+static inline int mei_sendrecv_icc(struct icc_header *icc,
+				   void *req_data, int req_bytes,
+				   void *rsp_data, int rsp_bytes)
+{
+	struct icc_header icc_rsp;
+
+	/* Send header */
+	if (mei_send_header(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS,
+			    icc, sizeof(*icc), req_bytes ? 0 : 1) < 0)
+		return -1;
+
+	/* Send data if available */
+	if (req_bytes && mei_send_data(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS,
+				       req_data, req_bytes) < 0)
+		return -1;
+
+	/* Read header and data, if needed */
+	if (rsp_bytes && mei_recv_msg(&icc_rsp, sizeof(icc_rsp),
+				      rsp_data, rsp_bytes) < 0)
+		return -1;
+
+	return 0;
+}
+
 /*
  * mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read
  * state machine on the BIOS end doesn't match the ME's state machine.
@@ -610,6 +634,30 @@ void intel_me_finalize_smm(void)
 
 #else /* !__SMM__ */
 
+static int me_icc_set_clock_enables(u32 mask)
+{
+	struct icc_clock_enables_msg clk = {
+		.clock_enables	= 0, /* Turn off specified clocks */
+		.clock_mask	= mask,
+		.no_response	= 1, /* Do not expect response */
+	};
+	struct icc_header icc = {
+		.api_version	= ICC_API_VERSION_LYNXPOINT,
+		.icc_command	= ICC_SET_CLOCK_ENABLES,
+		.length		= sizeof(clk),
+	};
+
+	/* Send request and wait for response */
+	if (mei_sendrecv_icc(&icc, &clk, sizeof(clk), NULL, 0) < 0) {
+		printk(BIOS_ERR, "ME: ICC SET CLOCK ENABLES message failed\n");
+		return -1;
+        } else {
+		printk(BIOS_INFO, "ME: ICC SET CLOCK ENABLES 0x%08x\n", mask);
+	}
+
+	return 0;
+}
+
 /* Determine the path that we should take based on ME status */
 static me_bios_path intel_me_path(device_t dev)
 {
@@ -760,6 +808,7 @@ static int intel_me_extend_valid(device_t dev)
 /* Check whether ME is present and do basic init */
 static void intel_me_init(device_t dev)
 {
+	struct southbridge_intel_lynxpoint_config *config = dev->chip_info;
 	me_bios_path path = intel_me_path(dev);
 	me_bios_payload mbp_data;
 
@@ -768,7 +817,6 @@ static void intel_me_init(device_t dev)
 
 	if (path == ME_NORMAL_BIOS_PATH) {
 		/* Validate the extend register */
-		/* FIXME: force recovery mode on failure. */
 		intel_me_extend_valid(dev);
 	}
 
@@ -800,6 +848,10 @@ static void intel_me_init(device_t dev)
 	}
 #endif
 
+	/* Set clock enables according to devicetree */
+	if (config && config->icc_clock_disable)
+		me_icc_set_clock_enables(config->icc_clock_disable);
+
 	/*
 	 * Leave the ME unlocked. It will be locked via SMI command later.
 	 */



More information about the coreboot-gerrit mailing list