^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013-2020, Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Intel Management Engine Interface (Intel MEI) Linux driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "mei_dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "hw-txe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "hbm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "mei-trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define TXE_HBUF_DEPTH (PAYLOAD_SIZE / MEI_SLOT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * mei_txe_reg_read - Reads 32bit data from the txe device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * @base_addr: registers base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * @offset: register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Return: register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static inline u32 mei_txe_reg_read(void __iomem *base_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return ioread32(base_addr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * mei_txe_reg_write - Writes 32bit data to the txe device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @base_addr: registers base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @offset: register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @value: the value to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static inline void mei_txe_reg_write(void __iomem *base_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) iowrite32(value, base_addr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * mei_txe_sec_reg_read_silent - Reads 32bit data from the SeC BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @offset: register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Doesn't check for aliveness while Reads 32bit data from the SeC BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Return: register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static inline u32 mei_txe_sec_reg_read_silent(struct mei_txe_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return mei_txe_reg_read(hw->mem_addr[SEC_BAR], offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * mei_txe_sec_reg_read - Reads 32bit data from the SeC BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @offset: register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Reads 32bit data from the SeC BAR and shout loud if aliveness is not set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Return: register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static inline u32 mei_txe_sec_reg_read(struct mei_txe_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) WARN(!hw->aliveness, "sec read: aliveness not asserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return mei_txe_sec_reg_read_silent(hw, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * mei_txe_sec_reg_write_silent - Writes 32bit data to the SeC BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * doesn't check for aliveness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @offset: register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @value: value to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Doesn't check for aliveness while writes 32bit data from to the SeC BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static inline void mei_txe_sec_reg_write_silent(struct mei_txe_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned long offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mei_txe_reg_write(hw->mem_addr[SEC_BAR], offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * mei_txe_sec_reg_write - Writes 32bit data to the SeC BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @offset: register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @value: value to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Writes 32bit data from the SeC BAR and shout loud if aliveness is not set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static inline void mei_txe_sec_reg_write(struct mei_txe_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned long offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) WARN(!hw->aliveness, "sec write: aliveness not asserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mei_txe_sec_reg_write_silent(hw, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * mei_txe_br_reg_read - Reads 32bit data from the Bridge BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @offset: offset from which to read the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Return: the byte read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static inline u32 mei_txe_br_reg_read(struct mei_txe_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return mei_txe_reg_read(hw->mem_addr[BRIDGE_BAR], offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * mei_txe_br_reg_write - Writes 32bit data to the Bridge BAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @offset: offset from which to write the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @value: the byte to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static inline void mei_txe_br_reg_write(struct mei_txe_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned long offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) mei_txe_reg_write(hw->mem_addr[BRIDGE_BAR], offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * mei_txe_aliveness_set - request for aliveness change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @req: requested aliveness value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Request for aliveness change and returns true if the change is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * really needed and false if aliveness is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * in the requested state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * Locking: called under "dev->device_lock" lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Return: true if request was send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) bool do_req = hw->aliveness != req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) dev_dbg(dev->dev, "Aliveness current=%d request=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) hw->aliveness, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (do_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dev->pg_event = MEI_PG_EVENT_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) mei_txe_br_reg_write(hw, SICR_HOST_ALIVENESS_REQ_REG, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return do_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * mei_txe_aliveness_req_get - get aliveness requested register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * Extract HICR_HOST_ALIVENESS_RESP_ACK bit from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * from HICR_HOST_ALIVENESS_REQ register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Return: SICR_HOST_ALIVENESS_REQ_REQUESTED bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static u32 mei_txe_aliveness_req_get(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) reg = mei_txe_br_reg_read(hw, SICR_HOST_ALIVENESS_REQ_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return reg & SICR_HOST_ALIVENESS_REQ_REQUESTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * mei_txe_aliveness_get - get aliveness response register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Return: HICR_HOST_ALIVENESS_RESP_ACK bit from HICR_HOST_ALIVENESS_RESP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static u32 mei_txe_aliveness_get(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) reg = mei_txe_br_reg_read(hw, HICR_HOST_ALIVENESS_RESP_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return reg & HICR_HOST_ALIVENESS_RESP_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * mei_txe_aliveness_poll - waits for aliveness to settle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * @expected: expected aliveness value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Polls for HICR_HOST_ALIVENESS_RESP.ALIVENESS_RESP to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * Return: 0 if the expected value was received, -ETIME otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ktime_t stop, start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) stop = ktime_add(start, ms_to_ktime(SEC_ALIVENESS_WAIT_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) hw->aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (hw->aliveness == expected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev->pg_event = MEI_PG_EVENT_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_dbg(dev->dev, "aliveness settled after %lld usecs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ktime_to_us(ktime_sub(ktime_get(), start)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) usleep_range(20, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) } while (ktime_before(ktime_get(), stop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dev->pg_event = MEI_PG_EVENT_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dev_err(dev->dev, "aliveness timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * mei_txe_aliveness_wait - waits for aliveness to settle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @expected: expected aliveness value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Waits for HICR_HOST_ALIVENESS_RESP.ALIVENESS_RESP to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * Return: 0 on success and < 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const unsigned long timeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) msecs_to_jiffies(SEC_ALIVENESS_WAIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) long err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) hw->aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (hw->aliveness == expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) mutex_unlock(&dev->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) err = wait_event_timeout(hw->wait_aliveness_resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev->pg_event == MEI_PG_EVENT_RECEIVED, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) mutex_lock(&dev->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) hw->aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = hw->aliveness == expected ? 0 : -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dev_warn(dev->dev, "aliveness timed out = %ld aliveness = %d event = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) err, hw->aliveness, dev->pg_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev_dbg(dev->dev, "aliveness settled after = %d msec aliveness = %d event = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) jiffies_to_msecs(timeout - err),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) hw->aliveness, dev->pg_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev->pg_event = MEI_PG_EVENT_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * mei_txe_aliveness_set_sync - sets an wait for aliveness to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * @req: requested aliveness value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * Return: 0 on success and < 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (mei_txe_aliveness_set(dev, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return mei_txe_aliveness_wait(dev, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * mei_txe_pg_in_transition - is device now in pg transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * Return: true if in pg transition, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static bool mei_txe_pg_in_transition(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return dev->pg_event == MEI_PG_EVENT_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * mei_txe_pg_is_enabled - detect if PG is supported by HW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Return: true is pg supported, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static bool mei_txe_pg_is_enabled(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * mei_txe_pg_state - translate aliveness register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * to the mei power gating state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * Return: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static inline enum mei_pg_state mei_txe_pg_state(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return hw->aliveness ? MEI_PG_OFF : MEI_PG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static void mei_txe_input_ready_interrupt_enable(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u32 hintmsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Enable the SEC_IPC_HOST_INT_MASK_IN_RDY interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) hintmsk = mei_txe_sec_reg_read(hw, SEC_IPC_HOST_INT_MASK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) hintmsk |= SEC_IPC_HOST_INT_MASK_IN_RDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mei_txe_sec_reg_write(hw, SEC_IPC_HOST_INT_MASK_REG, hintmsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * mei_txe_input_doorbell_set - sets bit 0 in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * SEC_IPC_INPUT_DOORBELL.IPC_INPUT_DOORBELL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void mei_txe_input_doorbell_set(struct mei_txe_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Clear the interrupt cause */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mei_txe_sec_reg_write(hw, SEC_IPC_INPUT_DOORBELL_REG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * mei_txe_output_ready_set - Sets the SICR_SEC_IPC_OUTPUT_STATUS bit to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * @hw: the txe hardware structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static void mei_txe_output_ready_set(struct mei_txe_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) mei_txe_br_reg_write(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) SICR_SEC_IPC_OUTPUT_STATUS_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) SEC_IPC_OUTPUT_STATUS_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * mei_txe_is_input_ready - check if TXE is ready for receiving data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Return: true if INPUT STATUS READY bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static bool mei_txe_is_input_ready(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) status = mei_txe_sec_reg_read(hw, SEC_IPC_INPUT_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return !!(SEC_IPC_INPUT_STATUS_RDY & status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * mei_txe_intr_clear - clear all interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static inline void mei_txe_intr_clear(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mei_txe_sec_reg_write_silent(hw, SEC_IPC_HOST_INT_STATUS_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SEC_IPC_HOST_INT_STATUS_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) mei_txe_br_reg_write(hw, HISR_REG, HISR_INT_STS_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) mei_txe_br_reg_write(hw, HHISR_REG, IPC_HHIER_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * mei_txe_intr_disable - disable all interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void mei_txe_intr_disable(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) mei_txe_br_reg_write(hw, HHIER_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) mei_txe_br_reg_write(hw, HIER_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * mei_txe_intr_enable - enable all interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static void mei_txe_intr_enable(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mei_txe_br_reg_write(hw, HHIER_REG, IPC_HHIER_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) mei_txe_br_reg_write(hw, HIER_REG, HIER_INT_EN_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * mei_txe_synchronize_irq - wait for pending IRQ handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static void mei_txe_synchronize_irq(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct pci_dev *pdev = to_pci_dev(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) synchronize_irq(pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * mei_txe_pending_interrupts - check if there are pending interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * only Aliveness, Input ready, and output doorbell are of relevance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Checks if there are pending interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * only Aliveness, Readiness, Input ready, and Output doorbell are relevant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * Return: true if there are pending interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static bool mei_txe_pending_interrupts(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) bool ret = (hw->intr_cause & (TXE_INTR_READINESS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) TXE_INTR_ALIVENESS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) TXE_INTR_IN_READY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) TXE_INTR_OUT_DB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_dbg(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) "Pending Interrupts InReady=%01d Readiness=%01d, Aliveness=%01d, OutDoor=%01d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) !!(hw->intr_cause & TXE_INTR_IN_READY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) !!(hw->intr_cause & TXE_INTR_READINESS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) !!(hw->intr_cause & TXE_INTR_ALIVENESS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) !!(hw->intr_cause & TXE_INTR_OUT_DB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * mei_txe_input_payload_write - write a dword to the host buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * at offset idx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * @idx: index in the host buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * @value: value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static void mei_txe_input_payload_write(struct mei_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) unsigned long idx, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) mei_txe_sec_reg_write(hw, SEC_IPC_INPUT_PAYLOAD_REG +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) (idx * sizeof(u32)), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * mei_txe_out_data_read - read dword from the device buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * at offset idx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * @idx: index in the device buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * Return: register value at index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static u32 mei_txe_out_data_read(const struct mei_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) unsigned long idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return mei_txe_br_reg_read(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) BRIDGE_IPC_OUTPUT_PAYLOAD_REG + (idx * sizeof(u32)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Readiness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * mei_txe_readiness_set_host_rdy - set host readiness bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static void mei_txe_readiness_set_host_rdy(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mei_txe_br_reg_write(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) SICR_HOST_IPC_READINESS_REQ_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) SICR_HOST_IPC_READINESS_HOST_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * mei_txe_readiness_clear - clear host readiness bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static void mei_txe_readiness_clear(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) mei_txe_br_reg_write(hw, SICR_HOST_IPC_READINESS_REQ_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) SICR_HOST_IPC_READINESS_RDY_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * mei_txe_readiness_get - Reads and returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * the HICR_SEC_IPC_READINESS register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * Return: the HICR_SEC_IPC_READINESS register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static u32 mei_txe_readiness_get(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return mei_txe_br_reg_read(hw, HICR_SEC_IPC_READINESS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * mei_txe_readiness_is_sec_rdy - check readiness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * for HICR_SEC_IPC_READINESS_SEC_RDY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @readiness: cached readiness state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * Return: true if readiness bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static inline bool mei_txe_readiness_is_sec_rdy(u32 readiness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return !!(readiness & HICR_SEC_IPC_READINESS_SEC_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * mei_txe_hw_is_ready - check if the hw is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * Return: true if sec is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static bool mei_txe_hw_is_ready(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) u32 readiness = mei_txe_readiness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return mei_txe_readiness_is_sec_rdy(readiness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * mei_txe_host_is_ready - check if the host is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * Return: true if host is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static inline bool mei_txe_host_is_ready(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) u32 reg = mei_txe_br_reg_read(hw, HICR_SEC_IPC_READINESS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return !!(reg & HICR_SEC_IPC_READINESS_HOST_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * mei_txe_readiness_wait - wait till readiness settles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * Return: 0 on success and -ETIME on timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static int mei_txe_readiness_wait(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (mei_txe_hw_is_ready(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) mutex_unlock(&dev->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) wait_event_timeout(dev->wait_hw_ready, dev->recvd_hw_ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) msecs_to_jiffies(SEC_RESET_WAIT_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) mutex_lock(&dev->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!dev->recvd_hw_ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dev_err(dev->dev, "wait for readiness failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dev->recvd_hw_ready = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static const struct mei_fw_status mei_txe_fw_sts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .status[0] = PCI_CFG_TXE_FW_STS0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .status[1] = PCI_CFG_TXE_FW_STS1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * mei_txe_fw_status - read fw status register from pci config space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * @dev: mei device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * @fw_status: fw status register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * Return: 0 on success, error otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static int mei_txe_fw_status(struct mei_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct mei_fw_status *fw_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) const struct mei_fw_status *fw_src = &mei_txe_fw_sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct pci_dev *pdev = to_pci_dev(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (!fw_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) fw_status->count = fw_src->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ret = pci_read_config_dword(pdev, fw_src->status[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &fw_status->status[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) trace_mei_pci_cfg_read(dev->dev, "PCI_CFG_HSF_X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) fw_src->status[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) fw_status->status[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * mei_txe_hw_config - configure hardware at the start of the devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Configure hardware at the start of the device should be done only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * once at the device probe time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * Return: always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static int mei_txe_hw_config(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) hw->aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) hw->readiness = mei_txe_readiness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev_dbg(dev->dev, "aliveness_resp = 0x%08x, readiness = 0x%08x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) hw->aliveness, hw->readiness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * mei_txe_write - writes a message to device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * @hdr: header of message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * @hdr_len: header length in bytes - must multiplication of a slot (4bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * @data: payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * @data_len: paylead length in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Return: 0 if success, < 0 - otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static int mei_txe_write(struct mei_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) const void *hdr, size_t hdr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) const void *data, size_t data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned long rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) const u32 *reg_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u32 slots = TXE_HBUF_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u32 dw_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) unsigned long i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (WARN_ON(!hdr || !data || hdr_len & 0x3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM((struct mei_msg_hdr *)hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dw_cnt = mei_data2slots(hdr_len + data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (dw_cnt > slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (WARN(!hw->aliveness, "txe write: aliveness not asserted\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* Enable Input Ready Interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) mei_txe_input_ready_interrupt_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (!mei_txe_is_input_ready(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) char fw_sts_str[MEI_FW_STATUS_STR_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_err(dev->dev, "Input is not ready %s\n", fw_sts_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) reg_buf = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) for (i = 0; i < hdr_len / MEI_SLOT_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) mei_txe_input_payload_write(dev, i, reg_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) reg_buf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) for (j = 0; j < data_len / MEI_SLOT_SIZE; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mei_txe_input_payload_write(dev, i + j, reg_buf[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) rem = data_len & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (rem > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) u32 reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) memcpy(®, (const u8 *)data + data_len - rem, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) mei_txe_input_payload_write(dev, i + j, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* after each write the whole buffer is consumed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) hw->slots = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* Set Input-Doorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) mei_txe_input_doorbell_set(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * mei_txe_hbuf_depth - mimics the me hbuf circular buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * Return: the TXE_HBUF_DEPTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static u32 mei_txe_hbuf_depth(const struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return TXE_HBUF_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * mei_txe_hbuf_empty_slots - mimics the me hbuf circular buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * Return: always TXE_HBUF_DEPTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int mei_txe_hbuf_empty_slots(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return hw->slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * mei_txe_count_full_read_slots - mimics the me device circular buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * Return: always buffer size in dwords count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static int mei_txe_count_full_read_slots(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /* read buffers has static size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return TXE_HBUF_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * mei_txe_read_hdr - read message header which is always in 4 first bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * Return: mei message header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static u32 mei_txe_read_hdr(const struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return mei_txe_out_data_read(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * mei_txe_read - reads a message from the txe device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * @buf: message buffer will be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * @len: message size will be read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * Return: -EINVAL on error wrong argument and 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static int mei_txe_read(struct mei_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned char *buf, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) u32 *reg_buf, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) u32 rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (WARN_ON(!buf || !len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) reg_buf = (u32 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) rem = len & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) dev_dbg(dev->dev, "buffer-length = %lu buf[0]0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) len, mei_txe_out_data_read(dev, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) for (i = 0; i < len / MEI_SLOT_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* skip header: index starts from 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) reg = mei_txe_out_data_read(dev, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dev_dbg(dev->dev, "buf[%d] = 0x%08X\n", i, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) *reg_buf++ = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) reg = mei_txe_out_data_read(dev, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) memcpy(reg_buf, ®, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) mei_txe_output_ready_set(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * mei_txe_hw_reset - resets host and fw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * @intr_enable: if interrupt should be enabled after reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * Return: 0 on success and < 0 in case of error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) u32 aliveness_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * read input doorbell to ensure consistency between Bridge and SeC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * return value might be garbage return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) (void)mei_txe_sec_reg_read_silent(hw, SEC_IPC_INPUT_DOORBELL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) aliveness_req = mei_txe_aliveness_req_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) hw->aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* Disable interrupts in this stage we will poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) mei_txe_intr_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * If Aliveness Request and Aliveness Response are not equal then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * wait for them to be equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * Since we might have interrupts disabled - poll for it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (aliveness_req != hw->aliveness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (mei_txe_aliveness_poll(dev, aliveness_req) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) dev_err(dev->dev, "wait for aliveness settle failed ... bailing out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * If Aliveness Request and Aliveness Response are set then clear them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (aliveness_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) mei_txe_aliveness_set(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (mei_txe_aliveness_poll(dev, 0) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_err(dev->dev, "wait for aliveness failed ... bailing out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * Set readiness RDY_CLR bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) mei_txe_readiness_clear(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * mei_txe_hw_start - start the hardware after reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * Return: 0 on success an error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static int mei_txe_hw_start(struct mei_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) u32 hisr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /* bring back interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) mei_txe_intr_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ret = mei_txe_readiness_wait(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) dev_err(dev->dev, "waiting for readiness failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * If HISR.INT2_STS interrupt status bit is set then clear it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) hisr = mei_txe_br_reg_read(hw, HISR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (hisr & HISR_INT_2_STS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) mei_txe_br_reg_write(hw, HISR_REG, HISR_INT_2_STS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /* Clear the interrupt cause of OutputDoorbell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) clear_bit(TXE_INTR_OUT_DB_BIT, &hw->intr_cause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) ret = mei_txe_aliveness_set_sync(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) dev_err(dev->dev, "wait for aliveness failed ... bailing out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) pm_runtime_set_active(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /* enable input ready interrupts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * SEC_IPC_HOST_INT_MASK.IPC_INPUT_READY_INT_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) mei_txe_input_ready_interrupt_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* Set the SICR_SEC_IPC_OUTPUT_STATUS.IPC_OUTPUT_READY bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) mei_txe_output_ready_set(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* Set bit SICR_HOST_IPC_READINESS.HOST_RDY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) mei_txe_readiness_set_host_rdy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * mei_txe_check_and_ack_intrs - translate multi BAR interrupt into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * single bit mask and acknowledge the interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * @do_ack: acknowledge interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * Return: true if found interrupts to process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) u32 hisr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) u32 hhisr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) u32 ipc_isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) u32 aliveness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) bool generated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* read interrupt registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) hhisr = mei_txe_br_reg_read(hw, HHISR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) generated = (hhisr & IPC_HHIER_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (!generated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) hisr = mei_txe_br_reg_read(hw, HISR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (hhisr & IPC_HHIER_SEC && aliveness) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ipc_isr = mei_txe_sec_reg_read_silent(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) SEC_IPC_HOST_INT_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ipc_isr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) hhisr &= ~IPC_HHIER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) generated = generated ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) (hisr & HISR_INT_STS_MSK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) (ipc_isr & SEC_IPC_HOST_INT_STATUS_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (generated && do_ack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* Save the interrupt causes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) hw->intr_cause |= hisr & HISR_INT_STS_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (ipc_isr & SEC_IPC_HOST_INT_STATUS_IN_RDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) hw->intr_cause |= TXE_INTR_IN_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) mei_txe_intr_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* Clear the interrupts in hierarchy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * IPC and Bridge, than the High Level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) mei_txe_sec_reg_write_silent(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) SEC_IPC_HOST_INT_STATUS_REG, ipc_isr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) mei_txe_br_reg_write(hw, HISR_REG, hisr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) mei_txe_br_reg_write(hw, HHISR_REG, hhisr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return generated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * mei_txe_irq_quick_handler - The ISR of the MEI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * @irq: The irq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * @dev_id: pointer to the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * Return: IRQ_WAKE_THREAD if interrupt is designed for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * IRQ_NONE otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct mei_device *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (mei_txe_check_and_ack_intrs(dev, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return IRQ_WAKE_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * mei_txe_irq_thread_handler - txe interrupt thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * @irq: The irq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * @dev_id: pointer to the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * Return: IRQ_HANDLED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) struct mei_device *dev = (struct mei_device *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct list_head cmpl_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) s32 slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int rets = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) dev_dbg(dev->dev, "irq thread: Interrupt Registers HHISR|HISR|SEC=%02X|%04X|%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) mei_txe_br_reg_read(hw, HHISR_REG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) mei_txe_br_reg_read(hw, HISR_REG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) mei_txe_sec_reg_read_silent(hw, SEC_IPC_HOST_INT_STATUS_REG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /* initialize our complete list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) mutex_lock(&dev->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) INIT_LIST_HEAD(&cmpl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (pci_dev_msi_enabled(to_pci_dev(dev->dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) mei_txe_check_and_ack_intrs(dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* show irq events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) mei_txe_pending_interrupts(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) hw->aliveness = mei_txe_aliveness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) hw->readiness = mei_txe_readiness_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* Readiness:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * Detection of TXE driver going through reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * or TXE driver resetting the HECI interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (test_and_clear_bit(TXE_INTR_READINESS_BIT, &hw->intr_cause)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) dev_dbg(dev->dev, "Readiness Interrupt was received...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* Check if SeC is going through reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (mei_txe_readiness_is_sec_rdy(hw->readiness)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dev_dbg(dev->dev, "we need to start the dev.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) dev->recvd_hw_ready = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) dev->recvd_hw_ready = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (dev->dev_state != MEI_DEV_RESETTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) dev_warn(dev->dev, "FW not ready: resetting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) schedule_work(&dev->reset_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) wake_up(&dev->wait_hw_ready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) /************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /* Check interrupt cause:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * Aliveness: Detection of SeC acknowledge of host request that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * it remain alive or host cancellation of that request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (test_and_clear_bit(TXE_INTR_ALIVENESS_BIT, &hw->intr_cause)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* Clear the interrupt cause */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dev_dbg(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) "Aliveness Interrupt: Status: %d\n", hw->aliveness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dev->pg_event = MEI_PG_EVENT_RECEIVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (waitqueue_active(&hw->wait_aliveness_resp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) wake_up(&hw->wait_aliveness_resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* Output Doorbell:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * Detection of SeC having sent output to host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) slots = mei_count_full_read_slots(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (test_and_clear_bit(TXE_INTR_OUT_DB_BIT, &hw->intr_cause)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /* Read from TXE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) rets = mei_irq_read_handler(dev, &cmpl_list, &slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (rets &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) (dev->dev_state != MEI_DEV_RESETTING &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) dev->dev_state != MEI_DEV_POWER_DOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) "mei_irq_read_handler ret = %d.\n", rets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) schedule_work(&dev->reset_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* Input Ready: Detection if host can write to SeC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (test_and_clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dev->hbuf_is_ready = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) hw->slots = TXE_HBUF_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (hw->aliveness && dev->hbuf_is_ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* get the real register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) rets = mei_irq_write_handler(dev, &cmpl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (rets && rets != -EMSGSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) dev_err(dev->dev, "mei_irq_write_handler ret = %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) rets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) mei_irq_compl_handler(dev, &cmpl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) dev_dbg(dev->dev, "interrupt thread end ret = %d\n", rets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) mutex_unlock(&dev->device_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mei_enable_interrupts(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static const struct mei_hw_ops mei_txe_hw_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) .host_is_ready = mei_txe_host_is_ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .fw_status = mei_txe_fw_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .pg_state = mei_txe_pg_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) .hw_is_ready = mei_txe_hw_is_ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) .hw_reset = mei_txe_hw_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) .hw_config = mei_txe_hw_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .hw_start = mei_txe_hw_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .pg_in_transition = mei_txe_pg_in_transition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .pg_is_enabled = mei_txe_pg_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) .intr_clear = mei_txe_intr_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) .intr_enable = mei_txe_intr_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) .intr_disable = mei_txe_intr_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) .synchronize_irq = mei_txe_synchronize_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) .hbuf_free_slots = mei_txe_hbuf_empty_slots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) .hbuf_is_ready = mei_txe_is_input_ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .hbuf_depth = mei_txe_hbuf_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .write = mei_txe_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) .rdbuf_full_slots = mei_txe_count_full_read_slots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) .read_hdr = mei_txe_read_hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) .read = mei_txe_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * mei_txe_dev_init - allocates and initializes txe hardware specific structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * @pdev: pci device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * Return: struct mei_device * on success or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) struct mei_device *mei_txe_dev_init(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) struct mei_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct mei_txe_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) dev = devm_kzalloc(&pdev->dev, sizeof(*dev) + sizeof(*hw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) mei_device_init(dev, &pdev->dev, &mei_txe_hw_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) init_waitqueue_head(&hw->wait_aliveness_resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * mei_txe_setup_satt2 - SATT2 configuration for DMA support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * @addr: physical address start of the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * @range: physical range size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * Return: 0 on success an error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) int mei_txe_setup_satt2(struct mei_device *dev, phys_addr_t addr, u32 range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct mei_txe_hw *hw = to_txe_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) u32 lo32 = lower_32_bits(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) u32 hi32 = upper_32_bits(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) u32 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /* SATT is limited to 36 Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (hi32 & ~0xF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /* SATT has to be 16Byte aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (lo32 & 0xF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /* SATT range has to be 4Bytes aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (range & 0x4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) /* SATT is limited to 32 MB range*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (range > SATT_RANGE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) ctrl = SATT2_CTRL_VALID_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ctrl |= hi32 << SATT2_CTRL_BR_BASE_ADDR_REG_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) mei_txe_br_reg_write(hw, SATT2_SAP_SIZE_REG, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) mei_txe_br_reg_write(hw, SATT2_BRG_BA_LSB_REG, lo32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) mei_txe_br_reg_write(hw, SATT2_CTRL_REG, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dev_dbg(dev->dev, "SATT2: SAP_SIZE_OFFSET=0x%08X, BRG_BA_LSB_OFFSET=0x%08X, CTRL_OFFSET=0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) range, lo32, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }