// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2013-2022, Intel Corporation. All rights reserved.
* Intel Management Engine Interface (Intel MEI) Linux driver
*/
#include <linux/pci.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/mei.h>
#include "mei_dev.h"
#include "hw-txe.h"
#include "client.h"
#include "hbm.h"
#include "mei-trace.h"
#define TXE_HBUF_DEPTH (PAYLOAD_SIZE / MEI_SLOT_SIZE)
/**
* mei_txe_reg_read - Reads 32bit data from the txe device
*
* @base_addr: registers base address
* @offset: register offset
*
* Return: register value
*/
static inline u32 mei_txe_reg_read(void __iomem *base_addr,
unsigned long offset)
{
return ioread32(base_addr + offset);
}
/**
* mei_txe_reg_write - Writes 32bit data to the txe device
*
* @base_addr: registers base address
* @offset: register offset
* @value: the value to write
*/
static inline void mei_txe_reg_write(void __iomem *base_addr,
unsigned long offset, u32 value)
{
iowrite32(value, base_addr + offset);
}
/**
* mei_txe_sec_reg_read_silent - Reads 32bit data from the SeC BAR
*
* @hw: the txe hardware structure
* @offset: register offset
*
* Doesn't check for aliveness while Reads 32bit data from the SeC BAR
*
* Return: register value
*/
static inline u32 mei_txe_sec_reg_read_silent(struct mei_txe_hw *hw,
unsigned long offset)
{
return mei_txe_reg_read(hw->mem_addr[SEC_BAR], offset);
}
/**
* mei_txe_sec_reg_read - Reads 32bit data from the SeC BAR
*
* @hw: the txe hardware structure
* @offset: register offset
*
* Reads 32bit data from the SeC BAR and shout loud if aliveness is not set
*
* Return: register value
*/
static inline u32 mei_txe_sec_reg_read(struct mei_txe_hw *hw,
unsigned long offset)
{
WARN(!hw->aliveness, "sec read: aliveness not asserted\n");
return mei_txe_sec_reg_read_silent(hw, offset);
}
/**
* mei_txe_sec_reg_write_silent - Writes 32bit data to the SeC BAR
* doesn't check for aliveness
*
* @hw: the txe hardware structure
* @offset: register offset
* @value: value to write
*
* Doesn't check for aliveness while writes 32bit data from to the SeC BAR
*/
static inline void mei_txe_sec_reg_write_silent(struct mei_txe_hw *hw,
unsigned long offset, u32 value)
{
mei_txe_reg_write(hw->mem_addr[SEC_BAR], offset, value);
}
/**
* mei_txe_sec_reg_write - Writes 32bit data to the SeC BAR
*
* @hw: the txe hardware structure
* @offset: register offset
* @value: value to write
*
* Writes 32bit data from the SeC BAR and shout loud if aliveness is not set
*/
static inline void mei_txe_sec_reg_write(struct mei_txe_hw *hw,
unsigned long offset, u32 value)
{
WARN(!hw->aliveness, "sec write: aliveness not asserted\n");
mei_txe_sec_reg_write_silent(hw, offset, value);
}
/**
* mei_txe_br_reg_read - Reads 32bit data from the Bridge BAR
*
* @hw: the txe hardware structure
* @offset: offset from which to read the data
*
* Return: the byte read.
*/
static inline u32 mei_txe_br_reg_read(struct mei_txe_hw *hw,
unsigned long offset)
{
return mei_txe_reg_read(hw->mem_addr[BRIDGE_BAR], offset);
}
/**
* mei_txe_br_reg_write - Writes 32bit data to the Bridge BAR
*
* @hw: the txe hardware structure
* @offset: offset from which to write the data
* @value: the byte to write
*/
static inline void mei_txe_br_reg_write(struct mei_txe_hw *hw,
unsigned long offset, u32 value)
{
mei_txe_reg_write(hw->mem_addr[BRIDGE_BAR], offset, value);
}
/**
* mei_txe_aliveness_set - request for aliveness change
*
* @dev: the device structure
* @req: requested aliveness value
*
* Request for aliveness change and returns true if the change is
* really needed and false if aliveness is already
* in the requested state
*
* Locking: called under "dev->device_lock" lock
*
* Return: true if request was send
*/
static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req)
{
struct mei_txe_hw *hw = to