mei: condition PGI support on HW and HBM version
authorTomas Winkler <tomas.winkler@intel.com>
Tue, 18 Mar 2014 20:51:58 +0000 (22:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 May 2014 23:20:23 +0000 (19:20 -0400)
Enable power gating isolation only if hw and fw support it.
This is indicated by ME_PGIC_HRA bit in ME_CSR_HA register
and on HBM protocol version.

The information is exported to MEI layer through
new pg_is_enabled hw op.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mei/hw-me.c
drivers/misc/mei/hw-txe.c
drivers/misc/mei/hw.h
drivers/misc/mei/mei_dev.h

index fc5d001983b32aac87227e8649819097941ab6e1..7a7e66250dfd7f1ff3b359a482b0170a91132136 100644 (file)
@@ -459,6 +459,41 @@ static void mei_me_pg_exit(struct mei_device *dev)
        mei_me_reg_write(hw, H_HPG_CSR, reg);
 }
 
+/**
+ * mei_me_pg_is_enabled - detect if PG is supported by HW
+ *
+ * @dev: the device structure
+ *
+ * returns: true is pg supported, false otherwise
+ */
+static bool mei_me_pg_is_enabled(struct mei_device *dev)
+{
+       struct mei_me_hw *hw = to_me_hw(dev);
+       u32 reg = mei_me_reg_read(hw, ME_CSR_HA);
+
+       if ((reg & ME_PGIC_HRA) == 0)
+               goto notsupported;
+
+       if (dev->version.major_version < HBM_MAJOR_VERSION_PGI)
+               goto notsupported;
+
+       if (dev->version.major_version == HBM_MAJOR_VERSION_PGI &&
+           dev->version.minor_version < HBM_MINOR_VERSION_PGI)
+               goto notsupported;
+
+       return true;
+
+notsupported:
+       dev_dbg(&dev->pdev->dev, "pg: not supported: HGP = %d hbm version %d.%d ?= %d.%d\n",
+               !!(reg & ME_PGIC_HRA),
+               dev->version.major_version,
+               dev->version.minor_version,
+               HBM_MAJOR_VERSION_PGI,
+               HBM_MINOR_VERSION_PGI);
+
+       return false;
+}
+
 /**
  * mei_me_irq_quick_handler - The ISR of the MEI device
  *
@@ -573,6 +608,8 @@ static const struct mei_hw_ops mei_me_hw_ops = {
        .hw_config = mei_me_hw_config,
        .hw_start = mei_me_hw_start,
 
+       .pg_is_enabled = mei_me_pg_is_enabled,
+
        .intr_clear = mei_me_intr_clear,
        .intr_enable = mei_me_intr_enable,
        .intr_disable = mei_me_intr_disable,
index f60182a52f964f438709af433efb0f80a27fcb24..49f197a956c9bbf0ba03dda85f6f2ac9fe973b8a 100644 (file)
@@ -279,6 +279,18 @@ int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req)
        return 0;
 }
 
+/**
+ * mei_txe_pg_is_enabled - detect if PG is supported by HW
+ *
+ * @dev: the device structure
+ *
+ * returns: true is pg supported, false otherwise
+ */
+static bool mei_txe_pg_is_enabled(struct mei_device *dev)
+{
+       return true;
+}
+
 /**
  * mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt
  *
@@ -1017,6 +1029,8 @@ static const struct mei_hw_ops mei_txe_hw_ops = {
        .hw_config = mei_txe_hw_config,
        .hw_start = mei_txe_hw_start,
 
+       .pg_is_enabled = mei_txe_pg_is_enabled,
+
        .intr_clear = mei_txe_intr_clear,
        .intr_enable = mei_txe_intr_enable,
        .intr_disable = mei_txe_intr_disable,
index 1d70968d90b685e6a052de7bc3a92f4d6bf59bf3..ec4a91a534e65369d36231b6dcf17b8e65dd634a 100644 (file)
 #define HBM_MINOR_VERSION                   0
 #define HBM_MAJOR_VERSION                   1
 
+/*
+ * MEI version with PGI support
+ */
+#define HBM_MINOR_VERSION_PGI               1
+#define HBM_MAJOR_VERSION_PGI               1
+
 /* Host bus message command opcode */
 #define MEI_HBM_CMD_OP_MSK                  0x7f
 /* Host bus message command RESPONSE */
index 4d4c041a7e4fa04ed551916150d1521e3f3f929b..ca7581ce072263e4127179db61f68e5f406f01b2 100644 (file)
@@ -220,6 +220,8 @@ struct mei_cl {
  * @hw_start         - start hw after reset
  * @hw_config        - configure hw
 
+ * @pg_is_enabled    - is power gating enabled
+
  * @intr_clear       - clear pending interrupts
  * @intr_enable      - enable interrupts
  * @intr_disable     - disable interrupts
@@ -244,6 +246,8 @@ struct mei_hw_ops {
        int (*hw_start)(struct mei_device *dev);
        void (*hw_config)(struct mei_device *dev);
 
+       bool (*pg_is_enabled)(struct mei_device *dev);
+
        void (*intr_clear)(struct mei_device *dev);
        void (*intr_enable)(struct mei_device *dev);
        void (*intr_disable)(struct mei_device *dev);
@@ -558,6 +562,12 @@ static inline void mei_hw_config(struct mei_device *dev)
 {
        dev->ops->hw_config(dev);
 }
+
+static inline bool mei_pg_is_enabled(struct mei_device *dev)
+{
+       return dev->ops->pg_is_enabled(dev);
+}
+
 static inline int mei_hw_reset(struct mei_device *dev, bool enable)
 {
        return dev->ops->hw_reset(dev, enable);