diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2014-03-18 16:51:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-03 19:20:23 -0400 |
commit | ee7e5afd2c369b64ffcf419d38ce7ad1c709a53e (patch) | |
tree | b61d3eea96f2fee5ab8209c44a41dced1e023a60 /drivers/misc | |
parent | b16c35716b843acdbe562bc0068580c50db203ff (diff) |
mei: condition PGI support on HW and HBM version
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>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/mei/hw-me.c | 37 | ||||
-rw-r--r-- | drivers/misc/mei/hw-txe.c | 14 | ||||
-rw-r--r-- | drivers/misc/mei/hw.h | 6 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 10 |
4 files changed, 67 insertions, 0 deletions
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index fc5d001983b3..7a7e66250dfd 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c | |||
@@ -460,6 +460,41 @@ static void mei_me_pg_exit(struct mei_device *dev) | |||
460 | } | 460 | } |
461 | 461 | ||
462 | /** | 462 | /** |
463 | * mei_me_pg_is_enabled - detect if PG is supported by HW | ||
464 | * | ||
465 | * @dev: the device structure | ||
466 | * | ||
467 | * returns: true is pg supported, false otherwise | ||
468 | */ | ||
469 | static bool mei_me_pg_is_enabled(struct mei_device *dev) | ||
470 | { | ||
471 | struct mei_me_hw *hw = to_me_hw(dev); | ||
472 | u32 reg = mei_me_reg_read(hw, ME_CSR_HA); | ||
473 | |||
474 | if ((reg & ME_PGIC_HRA) == 0) | ||
475 | goto notsupported; | ||
476 | |||
477 | if (dev->version.major_version < HBM_MAJOR_VERSION_PGI) | ||
478 | goto notsupported; | ||
479 | |||
480 | if (dev->version.major_version == HBM_MAJOR_VERSION_PGI && | ||
481 | dev->version.minor_version < HBM_MINOR_VERSION_PGI) | ||
482 | goto notsupported; | ||
483 | |||
484 | return true; | ||
485 | |||
486 | notsupported: | ||
487 | dev_dbg(&dev->pdev->dev, "pg: not supported: HGP = %d hbm version %d.%d ?= %d.%d\n", | ||
488 | !!(reg & ME_PGIC_HRA), | ||
489 | dev->version.major_version, | ||
490 | dev->version.minor_version, | ||
491 | HBM_MAJOR_VERSION_PGI, | ||
492 | HBM_MINOR_VERSION_PGI); | ||
493 | |||
494 | return false; | ||
495 | } | ||
496 | |||
497 | /** | ||
463 | * mei_me_irq_quick_handler - The ISR of the MEI device | 498 | * mei_me_irq_quick_handler - The ISR of the MEI device |
464 | * | 499 | * |
465 | * @irq: The irq number | 500 | * @irq: The irq number |
@@ -573,6 +608,8 @@ static const struct mei_hw_ops mei_me_hw_ops = { | |||
573 | .hw_config = mei_me_hw_config, | 608 | .hw_config = mei_me_hw_config, |
574 | .hw_start = mei_me_hw_start, | 609 | .hw_start = mei_me_hw_start, |
575 | 610 | ||
611 | .pg_is_enabled = mei_me_pg_is_enabled, | ||
612 | |||
576 | .intr_clear = mei_me_intr_clear, | 613 | .intr_clear = mei_me_intr_clear, |
577 | .intr_enable = mei_me_intr_enable, | 614 | .intr_enable = mei_me_intr_enable, |
578 | .intr_disable = mei_me_intr_disable, | 615 | .intr_disable = mei_me_intr_disable, |
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index f60182a52f96..49f197a956c9 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c | |||
@@ -280,6 +280,18 @@ int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | /** | 282 | /** |
283 | * mei_txe_pg_is_enabled - detect if PG is supported by HW | ||
284 | * | ||
285 | * @dev: the device structure | ||
286 | * | ||
287 | * returns: true is pg supported, false otherwise | ||
288 | */ | ||
289 | static bool mei_txe_pg_is_enabled(struct mei_device *dev) | ||
290 | { | ||
291 | return true; | ||
292 | } | ||
293 | |||
294 | /** | ||
283 | * mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt | 295 | * mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt |
284 | * | 296 | * |
285 | * @dev: the device structure | 297 | * @dev: the device structure |
@@ -1017,6 +1029,8 @@ static const struct mei_hw_ops mei_txe_hw_ops = { | |||
1017 | .hw_config = mei_txe_hw_config, | 1029 | .hw_config = mei_txe_hw_config, |
1018 | .hw_start = mei_txe_hw_start, | 1030 | .hw_start = mei_txe_hw_start, |
1019 | 1031 | ||
1032 | .pg_is_enabled = mei_txe_pg_is_enabled, | ||
1033 | |||
1020 | .intr_clear = mei_txe_intr_clear, | 1034 | .intr_clear = mei_txe_intr_clear, |
1021 | .intr_enable = mei_txe_intr_enable, | 1035 | .intr_enable = mei_txe_intr_enable, |
1022 | .intr_disable = mei_txe_intr_disable, | 1036 | .intr_disable = mei_txe_intr_disable, |
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index 1d70968d90b6..ec4a91a534e6 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h | |||
@@ -39,6 +39,12 @@ | |||
39 | #define HBM_MINOR_VERSION 0 | 39 | #define HBM_MINOR_VERSION 0 |
40 | #define HBM_MAJOR_VERSION 1 | 40 | #define HBM_MAJOR_VERSION 1 |
41 | 41 | ||
42 | /* | ||
43 | * MEI version with PGI support | ||
44 | */ | ||
45 | #define HBM_MINOR_VERSION_PGI 1 | ||
46 | #define HBM_MAJOR_VERSION_PGI 1 | ||
47 | |||
42 | /* Host bus message command opcode */ | 48 | /* Host bus message command opcode */ |
43 | #define MEI_HBM_CMD_OP_MSK 0x7f | 49 | #define MEI_HBM_CMD_OP_MSK 0x7f |
44 | /* Host bus message command RESPONSE */ | 50 | /* Host bus message command RESPONSE */ |
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 4d4c041a7e4f..ca7581ce0722 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -220,6 +220,8 @@ struct mei_cl { | |||
220 | * @hw_start - start hw after reset | 220 | * @hw_start - start hw after reset |
221 | * @hw_config - configure hw | 221 | * @hw_config - configure hw |
222 | 222 | ||
223 | * @pg_is_enabled - is power gating enabled | ||
224 | |||
223 | * @intr_clear - clear pending interrupts | 225 | * @intr_clear - clear pending interrupts |
224 | * @intr_enable - enable interrupts | 226 | * @intr_enable - enable interrupts |
225 | * @intr_disable - disable interrupts | 227 | * @intr_disable - disable interrupts |
@@ -244,6 +246,8 @@ struct mei_hw_ops { | |||
244 | int (*hw_start)(struct mei_device *dev); | 246 | int (*hw_start)(struct mei_device *dev); |
245 | void (*hw_config)(struct mei_device *dev); | 247 | void (*hw_config)(struct mei_device *dev); |
246 | 248 | ||
249 | bool (*pg_is_enabled)(struct mei_device *dev); | ||
250 | |||
247 | void (*intr_clear)(struct mei_device *dev); | 251 | void (*intr_clear)(struct mei_device *dev); |
248 | void (*intr_enable)(struct mei_device *dev); | 252 | void (*intr_enable)(struct mei_device *dev); |
249 | void (*intr_disable)(struct mei_device *dev); | 253 | void (*intr_disable)(struct mei_device *dev); |
@@ -558,6 +562,12 @@ static inline void mei_hw_config(struct mei_device *dev) | |||
558 | { | 562 | { |
559 | dev->ops->hw_config(dev); | 563 | dev->ops->hw_config(dev); |
560 | } | 564 | } |
565 | |||
566 | static inline bool mei_pg_is_enabled(struct mei_device *dev) | ||
567 | { | ||
568 | return dev->ops->pg_is_enabled(dev); | ||
569 | } | ||
570 | |||
561 | static inline int mei_hw_reset(struct mei_device *dev, bool enable) | 571 | static inline int mei_hw_reset(struct mei_device *dev, bool enable) |
562 | { | 572 | { |
563 | return dev->ops->hw_reset(dev, enable); | 573 | return dev->ops->hw_reset(dev, enable); |