mirror of
https://github.com/torvalds/linux.git
synced 2026-08-01 12:11:59 +02:00
bus: mhi: host: Add snapshot of MHI bus misc driver
This is a snapshot of MHI bus misc driver from msm-5.15
commit 1a84bdeed262 ("bus: mhi: core: Add snapshot
of MHI bus misc driver").
Change-Id: If606eee09983d27e291acb7fb85f268a1fe63cb2
Signed-off-by: Lazarus Motha <quic_lmotha@quicinc.com>
This commit is contained in:
parent
64dad0f665
commit
f1f4164c4f
|
|
@ -29,3 +29,11 @@ config MHI_BUS_PCI_GENERIC
|
|||
This driver provides MHI PCI controller driver for devices such as
|
||||
Qualcomm SDX55 based PCIe modems.
|
||||
|
||||
config MHI_BUS_MISC
|
||||
bool "Support for miscellaneous MHI features"
|
||||
depends on MHI_BUS
|
||||
help
|
||||
Miscellaneous features support for MHI Bus driver includes IPC logs,
|
||||
introduction of a list of controllers for debug using ramdumps and
|
||||
other features not present upstream such as Dynamic Resource Vote,
|
||||
SFR parsing using RDDM dumps, scanning for the RDDM cookie and more.
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
obj-$(CONFIG_MHI_BUS) += mhi.o
|
||||
mhi-y := init.o main.o pm.o boot.o
|
||||
mhi-$(CONFIG_MHI_BUS_MISC) += misc.o
|
||||
mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
|
||||
|
||||
obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define _MHI_INT_H
|
||||
|
||||
#include "../common.h"
|
||||
#include "misc.h"
|
||||
|
||||
extern struct bus_type mhi_bus_type;
|
||||
|
||||
|
|
|
|||
1913
drivers/bus/mhi/host/misc.c
Normal file
1913
drivers/bus/mhi/host/misc.c
Normal file
File diff suppressed because it is too large
Load Diff
340
drivers/bus/mhi/host/misc.h
Normal file
340
drivers/bus/mhi/host/misc.h
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */
|
||||
|
||||
#ifndef _MHI_CORE_MISC_H_
|
||||
#define _MHI_CORE_MISC_H_
|
||||
|
||||
#include <linux/mhi_misc.h>
|
||||
#include <linux/msm_pcie.h>
|
||||
|
||||
#define MHI_FORCE_WAKE_DELAY_US (100)
|
||||
#define MHI_IPC_LOG_PAGES (100)
|
||||
#define MAX_RDDM_TABLE_SIZE (8)
|
||||
#define MHI_REG_SIZE (SZ_4K)
|
||||
|
||||
#define REG_WRITE_QUEUE_LEN 512
|
||||
|
||||
/* MHI misc capability registers */
|
||||
#define MISC_OFFSET (0x24)
|
||||
#define MISC_CAP_MASK (0xFFFFFFFF)
|
||||
#define MISC_CAP_SHIFT (0)
|
||||
|
||||
#define CAP_CAPID_MASK (0xFF000000)
|
||||
#define CAP_CAPID_SHIFT (24)
|
||||
#define CAP_NEXT_CAP_MASK (0x00FFF000)
|
||||
#define CAP_NEXT_CAP_SHIFT (12)
|
||||
|
||||
/* MHI Bandwidth scaling offsets */
|
||||
#define BW_SCALE_CFG_OFFSET (0x04)
|
||||
#define BW_SCALE_CFG_CHAN_DB_ID_MASK (0xFE000000)
|
||||
#define BW_SCALE_CFG_CHAN_DB_ID_SHIFT (25)
|
||||
#define BW_SCALE_CFG_ENABLED_MASK (0x01000000)
|
||||
#define BW_SCALE_CFG_ENABLED_SHIFT (24)
|
||||
#define BW_SCALE_CFG_ER_ID_MASK (0x00F80000)
|
||||
#define BW_SCALE_CFG_ER_ID_SHIFT (19)
|
||||
|
||||
#define BW_SCALE_CAP_ID (3)
|
||||
#define MHI_TRE_GET_EV_BW_REQ_SEQ(tre) (((tre)->dword[0] >> 8) & 0xFF)
|
||||
#define MHI_BW_SCALE_CHAN_DB 126
|
||||
|
||||
#define MHI_BW_SCALE_SETUP(er_index) (((MHI_BW_SCALE_CHAN_DB << \
|
||||
BW_SCALE_CFG_CHAN_DB_ID_SHIFT) & BW_SCALE_CFG_CHAN_DB_ID_MASK) | \
|
||||
((1 << BW_SCALE_CFG_ENABLED_SHIFT) & BW_SCALE_CFG_ENABLED_MASK) | \
|
||||
(((er_index) << BW_SCALE_CFG_ER_ID_SHIFT) & BW_SCALE_CFG_ER_ID_MASK))
|
||||
|
||||
#define MHI_BW_SCALE_RESULT(status, seq) (((status) & 0xF) << 8 | \
|
||||
((seq) & 0xFF))
|
||||
#define MHI_BW_SCALE_NACK 0xF
|
||||
|
||||
/* subsystem failure reason cfg command */
|
||||
#define MHI_TRE_CMD_SFR_CFG_PTR(ptr) (ptr)
|
||||
#define MHI_TRE_CMD_SFR_CFG_DWORD0(len) (len)
|
||||
#define MHI_TRE_CMD_SFR_CFG_DWORD1 (MHI_CMD_SFR_CFG << 16)
|
||||
|
||||
/* MHI Timesync offsets */
|
||||
#define TIMESYNC_CFG_OFFSET (0x04)
|
||||
#define TIMESYNC_CFG_ENABLED_MASK (0x80000000)
|
||||
#define TIMESYNC_CFG_ENABLED_SHIFT (31)
|
||||
#define TIMESYNC_CFG_CHAN_DB_ID_MASK (0x0000FF00)
|
||||
#define TIMESYNC_CFG_CHAN_DB_ID_SHIFT (8)
|
||||
#define TIMESYNC_CFG_ER_ID_MASK (0x000000FF)
|
||||
#define TIMESYNC_CFG_ER_ID_SHIFT (0)
|
||||
|
||||
#define TIMESYNC_TIME_LOW_OFFSET (0x8)
|
||||
#define TIMESYNC_TIME_HIGH_OFFSET (0xC)
|
||||
|
||||
#define MHI_TIMESYNC_CHAN_DB (125)
|
||||
#define TIMESYNC_CAP_ID (2)
|
||||
|
||||
#define MHI_TIMESYNC_DB_SETUP(er_index) ((MHI_TIMESYNC_CHAN_DB << \
|
||||
TIMESYNC_CFG_CHAN_DB_ID_SHIFT) & TIMESYNC_CFG_CHAN_DB_ID_MASK | \
|
||||
(1 << TIMESYNC_CFG_ENABLED_SHIFT) & TIMESYNC_CFG_ENABLED_MASK | \
|
||||
((er_index) << TIMESYNC_CFG_ER_ID_SHIFT) & TIMESYNC_CFG_ER_ID_MASK)
|
||||
|
||||
#define MHI_VERB(dev, fmt, ...) do { \
|
||||
struct mhi_private *mhi_priv = \
|
||||
dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
|
||||
dev_dbg(dev, "[D][%s] " fmt, __func__, ##__VA_ARGS__); \
|
||||
if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_VERBOSE) \
|
||||
ipc_log_string(mhi_priv->log_buf, "[D][%s] " fmt, __func__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define MHI_LOG(dev, fmt, ...) do { \
|
||||
struct mhi_private *mhi_priv = \
|
||||
dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
|
||||
dev_dbg(dev, "[I][%s] " fmt, __func__, ##__VA_ARGS__); \
|
||||
if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_INFO) \
|
||||
ipc_log_string(mhi_priv->log_buf, "[I][%s] " fmt, __func__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define MHI_ERR(dev, fmt, ...) do { \
|
||||
struct mhi_private *mhi_priv = \
|
||||
dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
|
||||
dev_err(dev, "[E][%s] " fmt, __func__, ##__VA_ARGS__); \
|
||||
if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_ERROR) \
|
||||
ipc_log_string(mhi_priv->log_buf, "[E][%s] " fmt, __func__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define MHI_CRITICAL(dev, fmt, ...) do { \
|
||||
struct mhi_private *mhi_priv = \
|
||||
dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
|
||||
dev_crit(dev, "[C][%s] " fmt, __func__, ##__VA_ARGS__); \
|
||||
if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_CRITICAL) \
|
||||
ipc_log_string(mhi_priv->log_buf, "[C][%s] " fmt, __func__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* struct rddm_table_info - rddm table info
|
||||
* @base_address - Start offset of the file
|
||||
* @actual_phys_address - phys addr offset of file
|
||||
* @size - size of file
|
||||
* @description - file description
|
||||
* @file_name - name of file
|
||||
*/
|
||||
struct rddm_table_info {
|
||||
u64 base_address;
|
||||
u64 actual_phys_address;
|
||||
u64 size;
|
||||
char description[20];
|
||||
char file_name[20];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rddm_header - rddm header
|
||||
* @version - header ver
|
||||
* @header_size - size of header
|
||||
* @rddm_table_info - array of rddm table info
|
||||
*/
|
||||
struct rddm_header {
|
||||
u32 version;
|
||||
u32 header_size;
|
||||
struct rddm_table_info table_info[MAX_RDDM_TABLE_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct file_info - keeping track of file info while traversing the rddm
|
||||
* table header
|
||||
* @file_offset - current file offset
|
||||
* @seg_idx - mhi buf seg array index
|
||||
* @rem_seg_len - remaining length of the segment containing current file
|
||||
*/
|
||||
struct file_info {
|
||||
u8 *file_offset;
|
||||
u32 file_size;
|
||||
u32 seg_idx;
|
||||
u32 rem_seg_len;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct reg_write_info - offload reg write info
|
||||
* @reg_addr - register address
|
||||
* @val - value to be written to register
|
||||
* @chan - channel number
|
||||
* @valid - entry is valid or not
|
||||
*/
|
||||
struct reg_write_info {
|
||||
void __iomem *reg_addr;
|
||||
u32 val;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mhi_private - For private variables of an MHI controller
|
||||
*/
|
||||
struct mhi_private {
|
||||
struct list_head node;
|
||||
struct mhi_controller *mhi_cntrl;
|
||||
enum MHI_DEBUG_LEVEL log_lvl;
|
||||
void *log_buf;
|
||||
u32 saved_pm_state;
|
||||
enum mhi_state saved_dev_state;
|
||||
u32 m2_timeout_ms;
|
||||
void *priv_data;
|
||||
void __iomem *bw_scale_db;
|
||||
int (*bw_scale)(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_link_info *link_info);
|
||||
phys_addr_t base_addr;
|
||||
u32 numeric_id;
|
||||
u32 bw_response;
|
||||
struct mhi_sfr_info *sfr_info;
|
||||
struct mhi_timesync *timesync;
|
||||
|
||||
/* reg write offload */
|
||||
struct workqueue_struct *offload_wq;
|
||||
struct work_struct reg_write_work;
|
||||
struct reg_write_info *reg_write_q;
|
||||
atomic_t write_idx;
|
||||
u32 read_idx;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mhi_bus - For MHI controller debug
|
||||
*/
|
||||
struct mhi_bus {
|
||||
struct list_head controller_list;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mhi_sfr_info - For receiving MHI subsystem failure reason
|
||||
*/
|
||||
struct mhi_sfr_info {
|
||||
void *buf_addr;
|
||||
dma_addr_t dma_addr;
|
||||
size_t len;
|
||||
char *str;
|
||||
unsigned int ccs;
|
||||
struct completion completion;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mhi_timesync - For enabling use of MHI time synchronization feature
|
||||
*/
|
||||
struct mhi_timesync {
|
||||
u64 (*time_get)(struct mhi_controller *mhi_cntrl);
|
||||
int (*lpm_disable)(struct mhi_controller *mhi_cntrl);
|
||||
int (*lpm_enable)(struct mhi_controller *mhi_cntrl);
|
||||
void __iomem *time_reg;
|
||||
void __iomem *time_db;
|
||||
u32 int_sequence;
|
||||
u64 local_time;
|
||||
u64 remote_time;
|
||||
bool db_pending;
|
||||
struct completion completion;
|
||||
spinlock_t lock; /* list protection */
|
||||
struct list_head head;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tsync_node - Stores requests when using the timesync doorbell method
|
||||
*/
|
||||
struct tsync_node {
|
||||
struct list_head node;
|
||||
u32 sequence;
|
||||
u64 remote_time;
|
||||
struct mhi_device *mhi_dev;
|
||||
void (*cb_func)(struct mhi_device *mhi_dev, u32 sequence,
|
||||
u64 local_time, u64 remote_time);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MHI_BUS_MISC
|
||||
void mhi_misc_init(void);
|
||||
void mhi_misc_exit(void);
|
||||
int mhi_misc_init_mmio(struct mhi_controller *mhi_cntrl);
|
||||
int mhi_misc_register_controller(struct mhi_controller *mhi_cntrl);
|
||||
void mhi_misc_unregister_controller(struct mhi_controller *mhi_cntrl);
|
||||
int mhi_process_misc_bw_ev_ring(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_event *mhi_event, u32 event_quota);
|
||||
int mhi_process_misc_tsync_ev_ring(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_event *mhi_event, u32 event_quota);
|
||||
void mhi_misc_mission_mode(struct mhi_controller *mhi_cntrl);
|
||||
void mhi_misc_dbs_pending(struct mhi_controller *mhi_cntrl);
|
||||
void mhi_misc_disable(struct mhi_controller *mhi_cntrl);
|
||||
void mhi_misc_cmd_configure(struct mhi_controller *mhi_cntrl,
|
||||
unsigned int type, u64 *ptr, u32 *dword0,
|
||||
u32 *dword1);
|
||||
void mhi_misc_cmd_completion(struct mhi_controller *mhi_cntrl,
|
||||
unsigned int type, unsigned int ccs);
|
||||
void mhi_write_offload_wakedb(struct mhi_controller *mhi_cntrl, int db_val);
|
||||
void mhi_reset_reg_write_q(struct mhi_controller *mhi_cntrl);
|
||||
void mhi_force_reg_write(struct mhi_controller *mhi_cntrl);
|
||||
#else
|
||||
static inline void mhi_misc_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mhi_misc_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int mhi_misc_init_mmio(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mhi_misc_register_controller(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void mhi_misc_unregister_controller(struct mhi_controller
|
||||
*mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int mhi_process_misc_bw_ev_ring(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_event *mhi_event, u32 event_quota)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mhi_process_misc_tsync_ev_ring
|
||||
(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_event *mhi_event, u32 event_quota)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void mhi_misc_mission_mode(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mhi_special_dbs_pending(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mhi_misc_disable(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mhi_misc_cmd_configure(struct mhi_controller *mhi_cntrl,
|
||||
unsigned int type, u64 *ptr,
|
||||
u32 *dword0, u32 *dword1)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mhi_misc_cmd_completion(struct mhi_controller *mhi_cntrl,
|
||||
unsigned int type, unsigned int ccs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mhi_write_offload_wakedb(struct mhi_controller *mhi_cntrl,
|
||||
int db_val)
|
||||
{
|
||||
}
|
||||
|
||||
void mhi_reset_reg_write_q(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
void mhi_force_reg_write(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MHI_CORE_MISC_H_ */
|
||||
669
include/linux/mhi_misc.h
Normal file
669
include/linux/mhi_misc.h
Normal file
|
|
@ -0,0 +1,669 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */
|
||||
|
||||
#ifndef _MHI_MISC_H_
|
||||
#define _MHI_MISC_H_
|
||||
|
||||
#include <linux/mhi.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
|
||||
/**
|
||||
* enum MHI_DEBUG_LEVEL - various debugging levels
|
||||
*/
|
||||
enum MHI_DEBUG_LEVEL {
|
||||
MHI_MSG_LVL_VERBOSE,
|
||||
MHI_MSG_LVL_INFO,
|
||||
MHI_MSG_LVL_ERROR,
|
||||
MHI_MSG_LVL_CRITICAL,
|
||||
MHI_MSG_LVL_MASK_ALL,
|
||||
MHI_MSG_LVL_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mhi_buf - MHI Buffer description
|
||||
* @node: list entry point
|
||||
* @buf: Virtual address of the buffer
|
||||
* @name: Buffer label. For offload channel, configurations name must be:
|
||||
* ECA - Event context array data
|
||||
* CCA - Channel context array data
|
||||
* @dma_addr: IOMMU address of the buffer
|
||||
* @phys_addr: physical address of the buffer
|
||||
* @len: # of bytes
|
||||
* @is_io: buffer is of IO/registesr type (resource) rather than of DDR/RAM type
|
||||
*/
|
||||
struct mhi_buf_extended {
|
||||
struct list_head node;
|
||||
void *buf;
|
||||
const char *name;
|
||||
dma_addr_t dma_addr;
|
||||
phys_addr_t phys_addr;
|
||||
size_t len;
|
||||
bool is_io;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MHI_BUS_MISC
|
||||
|
||||
/**
|
||||
* mhi_report_error - Can be used by controller to signal error condition to the
|
||||
* MHI core driver in case of any need to halt processing or incoming sideband
|
||||
* signal detects an error on endpoint
|
||||
* @mhi_cntrl: MHI controller
|
||||
*
|
||||
* Returns:
|
||||
* 0 if success in reporting the error condition to MHI core
|
||||
* error code on failure
|
||||
*/
|
||||
int mhi_report_error(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/**
|
||||
* mhi_controller_set_privdata - Set private data for MHI controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @priv: pointer to data
|
||||
*/
|
||||
void mhi_controller_set_privdata(struct mhi_controller *mhi_cntrl, void *priv);
|
||||
|
||||
/**
|
||||
* mhi_controller_get_privdata - Get private data from MHI controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
void *mhi_controller_get_privdata(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/**
|
||||
* mhi_bdf_to_controller - Get controller associated with given BDF values
|
||||
* @domain: Domain or root complex of PCIe port
|
||||
* @bus: Bus number
|
||||
* @slot: PCI slot or function number
|
||||
* @dev_id: Device ID of the endpoint
|
||||
*
|
||||
* Returns:
|
||||
* MHI controller structure pointer if BDF match is found
|
||||
* NULL if cookie is not found
|
||||
*/
|
||||
struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id);
|
||||
|
||||
/**
|
||||
* mhi_set_m2_timeout_ms - Set M2 timeout in milliseconds to wait before a
|
||||
* fast/silent suspend
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @timeout: timeout in ms
|
||||
*/
|
||||
void mhi_set_m2_timeout_ms(struct mhi_controller *mhi_cntrl, u32 timeout);
|
||||
|
||||
/**
|
||||
* mhi_pm_fast_resume - Resume MHI from a fast/silent suspended state
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @notify_clients: if true, clients will be notified of the resume transition
|
||||
*/
|
||||
int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_clients);
|
||||
|
||||
/**
|
||||
* mhi_pm_fast_suspend - Move MHI into a fast/silent suspended state
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @notify_clients: if true, clients will be notified of the suspend transition
|
||||
*/
|
||||
int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_clients);
|
||||
|
||||
/**
|
||||
* mhi_debug_reg_dump - dump MHI registers for debug purpose
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/**
|
||||
* mhi_dump_sfr - Print SFR string from RDDM table.
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
void mhi_dump_sfr(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/**
|
||||
* mhi_device_configure - Allow devices with offload channels to setup their own
|
||||
* channel and event ring context.
|
||||
* @mhi_dev: MHI device
|
||||
* @dir: direction associated with the channel needed to configure
|
||||
* @cfg_tbl: Buffer with ECA/CCA information and data needed to setup context
|
||||
* @elements: Number of items to iterate over from the configuration table
|
||||
*/
|
||||
int mhi_device_configure(struct mhi_device *mhi_dev,
|
||||
enum dma_data_direction dir,
|
||||
struct mhi_buf *cfg_tbl,
|
||||
int elements);
|
||||
|
||||
/**
|
||||
* mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
|
||||
* registers set by device to indicate rddm readiness for debugging purposes.
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @cookie: cookie/pattern value to match
|
||||
*
|
||||
* Returns:
|
||||
* true if cookie is found
|
||||
* false if cookie is not found
|
||||
*/
|
||||
bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie);
|
||||
|
||||
/**
|
||||
* mhi_device_get_sync_atomic - Asserts device_wait and moves device to M0
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @timeout_us: timeout, in micro-seconds
|
||||
* @in_panic: If requested while kernel is in panic state and no ISRs expected
|
||||
*
|
||||
* The device_wake is asserted to keep device in M0 or bring it to M0.
|
||||
* If device is not in M0 state, then this function will wait for device to
|
||||
* move to M0, until @timeout_us elapses.
|
||||
* However, if device's M1 state-change event races with this function
|
||||
* then there is a possiblity of device moving from M0 to M2 and back
|
||||
* to M0. That can't be avoided as host must transition device from M1 to M2
|
||||
* as per the spec.
|
||||
* Clients can ignore that transition after this function returns as the device
|
||||
* is expected to immediately move from M2 to M0 as wake is asserted and
|
||||
* wouldn't enter low power state.
|
||||
* If in_panic boolean is set, no ISRs are expected, hence this API will have to
|
||||
* resort to reading the MHI status register and poll on M0 state change.
|
||||
*
|
||||
* Returns:
|
||||
* 0 if operation was successful (however, M0 -> M2 -> M0 is possible later) as
|
||||
* mentioned above.
|
||||
* -ETIMEDOUT is device faled to move to M0 before @timeout_us elapsed
|
||||
* -EIO if the MHI state is one of the ERROR states.
|
||||
*/
|
||||
int mhi_device_get_sync_atomic(struct mhi_device *mhi_dev, int timeout_us,
|
||||
bool in_panic);
|
||||
|
||||
/**
|
||||
* mhi_controller_set_bw_scale_cb - Set the BW scale callback for MHI controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @cb_func: Callback to set for the MHI controller to receive BW scale requests
|
||||
*/
|
||||
void mhi_controller_set_bw_scale_cb(struct mhi_controller *mhi_cntrl,
|
||||
int (*cb_func)(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_link_info *link_info));
|
||||
/**
|
||||
* mhi_controller_set_base - Set the controller base / resource start address
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @base: Physical address to be set for future reference
|
||||
*/
|
||||
void mhi_controller_set_base(struct mhi_controller *mhi_cntrl,
|
||||
phys_addr_t base);
|
||||
|
||||
/**
|
||||
* mhi_controller_get_base - Get the controller base / resource start address
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @base: Pointer to physical address to be populated
|
||||
*/
|
||||
int mhi_controller_get_base(struct mhi_controller *mhi_cntrl,
|
||||
phys_addr_t *base);
|
||||
|
||||
/**
|
||||
* mhi_controller_get_numeric_id - set numeric ID for controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
* returns value set as ID or 0 if no value was set
|
||||
*/
|
||||
u32 mhi_controller_get_numeric_id(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/**
|
||||
* mhi_get_channel_db_base - retrieve the channel doorbell base address
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @value: Pointer to an address value which will be populated
|
||||
*/
|
||||
int mhi_get_channel_db_base(struct mhi_device *mhi_dev, phys_addr_t *value);
|
||||
|
||||
/**
|
||||
* mhi_get_event_ring_db_base - retrieve the event ring doorbell base address
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @value: Pointer to an address value which will be populated
|
||||
*/
|
||||
int mhi_get_event_ring_db_base(struct mhi_device *mhi_dev, phys_addr_t *value);
|
||||
|
||||
/**
|
||||
* mhi_get_device_for_channel - get the MHI device for a specific channel number
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @channel - channel number
|
||||
*
|
||||
* Returns:
|
||||
* Pointer to the MHI device associated with the channel
|
||||
*/
|
||||
struct mhi_device *mhi_get_device_for_channel(struct mhi_controller *mhi_cntrl,
|
||||
u32 channel);
|
||||
|
||||
/**
|
||||
* mhi_device_ioctl - user space IOCTL support for MHI channels
|
||||
* Native support for setting TIOCM
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @cmd: IOCTL cmd
|
||||
* @arg: Optional parameter, iotcl cmd specific
|
||||
*/
|
||||
long mhi_device_ioctl(struct mhi_device *mhi_dev, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
/**
|
||||
* mhi_controller_set_sfr_support - Set support for subsystem failure reason
|
||||
* @mhi_cntrl: MHI controller
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_controller_set_sfr_support(struct mhi_controller *mhi_cntrl,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* mhi_controller_setup_timesync - Set support for time synchronization feature
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @time_get: Callback to set for the MHI controller to receive host time
|
||||
* @lpm_disable: Callback to set for the MHI controller to disable link LPM
|
||||
* @lpm_enable: Callback to set for the MHI controller to enable link LPM
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_controller_setup_timesync(struct mhi_controller *mhi_cntrl,
|
||||
u64 (*time_get)(struct mhi_controller *c),
|
||||
int (*lpm_disable)(struct mhi_controller *c),
|
||||
int (*lpm_enable)(struct mhi_controller *c));
|
||||
|
||||
/**
|
||||
* mhi_get_remote_time_sync - Get external soc time relative to local soc time
|
||||
* using MMIO method.
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @t_host: Pointer to output local soc time
|
||||
* @t_dev: Pointer to output remote soc time
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
|
||||
u64 *t_host,
|
||||
u64 *t_dev);
|
||||
|
||||
/**
|
||||
* mhi_get_remote_time - Get external modem time relative to host time
|
||||
* Trigger event to capture modem time, also capture host time so client
|
||||
* can do a relative drift comparision.
|
||||
* Recommended only tsync device calls this method and do not call this
|
||||
* from atomic context
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @sequence:unique sequence id track event
|
||||
* @cb_func: callback function to call back
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_get_remote_time(struct mhi_device *mhi_dev,
|
||||
u32 sequence,
|
||||
void (*cb_func)(struct mhi_device *mhi_dev,
|
||||
u32 sequence,
|
||||
u64 local_time,
|
||||
u64 remote_time));
|
||||
|
||||
/**
|
||||
* mhi_force_reset - does host reset request to collect device side dumps
|
||||
* for debugging purpose
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
int mhi_force_reset(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
/**
|
||||
* mhi_controller_set_loglevel - API for controller to set a desired log level
|
||||
* which will be set to VERBOSE or 0 by default
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @lvl: Log level from MHI_DEBUG_LEVEL enumerator
|
||||
*/
|
||||
void mhi_controller_set_loglevel(struct mhi_controller *mhi_cntrl,
|
||||
enum MHI_DEBUG_LEVEL lvl);
|
||||
|
||||
/**
|
||||
* mhi_get_soc_info - Get SoC info before registering mhi controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
int mhi_get_soc_info(struct mhi_controller *mhi_cntrl);
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* mhi_report_error - Can be used by controller to signal error condition to the
|
||||
* MHI core driver in case of any need to halt processing or incoming sideband
|
||||
* signal detects an error on endpoint
|
||||
* @mhi_cntrl: MHI controller
|
||||
*
|
||||
* Returns:
|
||||
* 0 if success in reporting the error condition to MHI core
|
||||
* error code on failure
|
||||
*/
|
||||
static inline int mhi_report_error(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_set_privdata - Set private data for MHI controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @priv: pointer to data
|
||||
*/
|
||||
void mhi_controller_set_privdata(struct mhi_controller *mhi_cntrl, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_get_privdata - Get private data from MHI controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
void *mhi_controller_get_privdata(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_bdf_to_controller - Get controller associated with given BDF values
|
||||
* @domain: Domain or root complex of PCIe port
|
||||
* @bus: Bus number
|
||||
* @slot: PCI slot or function number
|
||||
* @dev_id: Device ID of the endpoint
|
||||
*
|
||||
* Returns:
|
||||
* MHI controller structure pointer if BDF match is found
|
||||
* NULL if cookie is not found
|
||||
*/
|
||||
struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_set_m2_timeout_ms - Set M2 timeout in milliseconds to wait before a
|
||||
* fast/silent suspend
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @timeout: timeout in ms
|
||||
*/
|
||||
void mhi_set_m2_timeout_ms(struct mhi_controller *mhi_cntrl, u32 timeout)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_pm_fast_resume - Resume MHI from a fast/silent suspended state
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @notify_clients: if true, clients will be notified of the resume transition
|
||||
*/
|
||||
int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_clients)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_pm_fast_suspend - Move MHI into a fast/silent suspended state
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @notify_clients: if true, clients will be notified of the suspend transition
|
||||
*/
|
||||
int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_clients)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_debug_reg_dump - dump MHI registers for debug purpose
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_dump_sfr - Print SFR string from RDDM table.
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
void mhi_dump_sfr(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_device_configure - Allow devices with offload channels to setup their own
|
||||
* channel and event ring context.
|
||||
* @mhi_dev: MHI device
|
||||
* @dir: direction associated with the channel needed to configure
|
||||
* @cfg_tbl: Buffer with ECA/CCA information and data needed to setup context
|
||||
* @elements: Number of items to iterate over from the configuration table
|
||||
*/
|
||||
int mhi_device_configure(struct mhi_device *mhi_dev,
|
||||
enum dma_data_direction dir,
|
||||
struct mhi_buf *cfg_tbl,
|
||||
int elements)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
|
||||
* registers set by device to indicate rddm readiness for debugging purposes.
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @cookie: cookie/pattern value to match
|
||||
*
|
||||
* Returns:
|
||||
* true if cookie is found
|
||||
* false if cookie is not found
|
||||
*/
|
||||
bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_device_get_sync_atomic - Asserts device_wait and moves device to M0
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @timeout_us: timeout, in micro-seconds
|
||||
* @in_panic: If requested while kernel is in panic state and no ISRs expected
|
||||
*
|
||||
* The device_wake is asserted to keep device in M0 or bring it to M0.
|
||||
* If device is not in M0 state, then this function will wait for device to
|
||||
* move to M0, until @timeout_us elapses.
|
||||
* However, if device's M1 state-change event races with this function
|
||||
* then there is a possiblity of device moving from M0 to M2 and back
|
||||
* to M0. That can't be avoided as host must transition device from M1 to M2
|
||||
* as per the spec.
|
||||
* Clients can ignore that transition after this function returns as the device
|
||||
* is expected to immediately move from M2 to M0 as wake is asserted and
|
||||
* wouldn't enter low power state.
|
||||
* If in_panic boolean is set, no ISRs are expected, hence this API will have to
|
||||
* resort to reading the MHI status register and poll on M0 state change.
|
||||
*
|
||||
* Returns:
|
||||
* 0 if operation was successful (however, M0 -> M2 -> M0 is possible later) as
|
||||
* mentioned above.
|
||||
* -ETIMEDOUT is device faled to move to M0 before @timeout_us elapsed
|
||||
* -EIO if the MHI state is one of the ERROR states.
|
||||
*/
|
||||
int mhi_device_get_sync_atomic(struct mhi_device *mhi_dev, int timeout_us,
|
||||
bool in_panic)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_set_bw_scale_cb - Set the BW scale callback for MHI controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @cb_func: Callback to set for the MHI controller to receive BW scale requests
|
||||
*/
|
||||
void mhi_controller_set_bw_scale_cb(struct mhi_controller *mhi_cntrl,
|
||||
int (*cb_func)(struct mhi_controller *mhi_cntrl,
|
||||
struct mhi_link_info *link_info))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_set_base - Set the controller base / resource start address
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @base: Physical address to be set for future reference
|
||||
*/
|
||||
void mhi_controller_set_base(struct mhi_controller *mhi_cntrl,
|
||||
phys_addr_t base)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_get_base - Get the controller base / resource start address
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @base: Pointer to physical address to be populated
|
||||
*/
|
||||
int mhi_controller_get_base(struct mhi_controller *mhi_cntrl,
|
||||
phys_addr_t *base)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_get_numeric_id - set numeric ID for controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
* returns value set as ID or 0 if no value was set
|
||||
*/
|
||||
u32 mhi_controller_get_numeric_id(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_get_channel_db_base - retrieve the channel doorbell base address
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @value: Pointer to an address value which will be populated
|
||||
*/
|
||||
int mhi_get_channel_db_base(struct mhi_device *mhi_dev, phys_addr_t *value)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_get_event_ring_db_base - retrieve the event ring doorbell base address
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @value: Pointer to an address value which will be populated
|
||||
*/
|
||||
int mhi_get_event_ring_db_base(struct mhi_device *mhi_dev, phys_addr_t *value)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_get_device_for_channel - get the MHI device for a specific channel number
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @channel - channel number
|
||||
*
|
||||
* Returns:
|
||||
* Pointer to the MHI device associated with the channel
|
||||
*/
|
||||
struct mhi_device *mhi_get_device_for_channel(struct mhi_controller *mhi_cntrl,
|
||||
u32 channel)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_device_ioctl - user space IOCTL support for MHI channels
|
||||
* Native support for setting TIOCM
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @cmd: IOCTL cmd
|
||||
* @arg: Optional parameter, iotcl cmd specific
|
||||
*/
|
||||
long mhi_device_ioctl(struct mhi_device *mhi_dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_set_sfr_support - Set support for subsystem failure reason
|
||||
* @mhi_cntrl: MHI controller
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_controller_set_sfr_support(struct mhi_controller *mhi_cntrl,
|
||||
size_t len)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_setup_timesync - Set support for time synchronization feature
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @time_get: Callback to set for the MHI controller to receive host time
|
||||
* @lpm_disable: Callback to set for the MHI controller to disable link LPM
|
||||
* @lpm_enable: Callback to set for the MHI controller to enable link LPM
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_controller_setup_timesync(struct mhi_controller *mhi_cntrl,
|
||||
u64 (*time_get)(struct mhi_controller *c),
|
||||
int (*lpm_disable)(struct mhi_controller *c),
|
||||
int (*lpm_enable)(struct mhi_controller *c))
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_get_remote_time_sync - Get external soc time relative to local soc time
|
||||
* using MMIO method.
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @t_host: Pointer to output local soc time
|
||||
* @t_dev: Pointer to output remote soc time
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
|
||||
u64 *t_host,
|
||||
u64 *t_dev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_get_remote_time - Get external modem time relative to host time
|
||||
* Trigger event to capture modem time, also capture host time so client
|
||||
* can do a relative drift comparision.
|
||||
* Recommended only tsync device calls this method and do not call this
|
||||
* from atomic context
|
||||
* @mhi_dev: Device associated with the channels
|
||||
* @sequence:unique sequence id track event
|
||||
* @cb_func: callback function to call back
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, error code for failure
|
||||
*/
|
||||
int mhi_get_remote_time(struct mhi_device *mhi_dev,
|
||||
u32 sequence,
|
||||
void (*cb_func)(struct mhi_device *mhi_dev,
|
||||
u32 sequence,
|
||||
u64 local_time,
|
||||
u64 remote_time))
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_force_reset - does host reset request to collect device side dumps
|
||||
* for debugging purpose
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
int mhi_force_reset(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_controller_set_loglevel - API for controller to set a desired log level
|
||||
* which will be set to VERBOSE or 0 by default
|
||||
* @mhi_cntrl: MHI controller
|
||||
* @lvl: Log level from MHI_DEBUG_LEVEL enumerator
|
||||
*/
|
||||
void mhi_controller_set_loglevel(struct mhi_controller *mhi_cntrl,
|
||||
enum MHI_DEBUG_LEVEL lvl)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* mhi_get_soc_info - Get SoC info before registering mhi controller
|
||||
* @mhi_cntrl: MHI controller
|
||||
*/
|
||||
int mhi_get_soc_info(struct mhi_controller *mhi_cntrl)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MHI_BUS_MISC */
|
||||
|
||||
#endif /* _MHI_MISC_H_ */
|
||||
Loading…
Reference in New Issue
Block a user