Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee7e5afd authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b16c3571
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -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,
+14 −0
Original line number Diff line number Diff line
@@ -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,
+6 −0
Original line number Diff line number Diff line
@@ -39,6 +39,12 @@
#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 */
+10 −0
Original line number Diff line number Diff line
@@ -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);