brintos

brintos / linux-shallow public Read only

0
0
Text · 13.4 KiB · d057e87 Raw
424 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.4 *5 */6 7#ifndef _MHI_INT_H8#define _MHI_INT_H9 10#include "../common.h"11 12extern const struct bus_type mhi_bus_type;13 14/* Host request register */15#define MHI_SOC_RESET_REQ_OFFSET			0xb016#define MHI_SOC_RESET_REQ				BIT(0)17 18struct mhi_ctxt {19	struct mhi_event_ctxt *er_ctxt;20	struct mhi_chan_ctxt *chan_ctxt;21	struct mhi_cmd_ctxt *cmd_ctxt;22	dma_addr_t er_ctxt_addr;23	dma_addr_t chan_ctxt_addr;24	dma_addr_t cmd_ctxt_addr;25};26 27struct bhi_vec_entry {28	u64 dma_addr;29	u64 size;30};31 32enum mhi_ch_state_type {33	MHI_CH_STATE_TYPE_RESET,34	MHI_CH_STATE_TYPE_STOP,35	MHI_CH_STATE_TYPE_START,36	MHI_CH_STATE_TYPE_MAX,37};38 39#define MHI_CH_STATE_TYPE_LIST				\40	ch_state_type(RESET,		"RESET")	\41	ch_state_type(STOP,		"STOP")		\42	ch_state_type_end(START,	"START")43 44extern const char * const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX];45#define TO_CH_STATE_TYPE_STR(state) (((state) >= MHI_CH_STATE_TYPE_MAX) ? \46				     "INVALID_STATE" : \47				     mhi_ch_state_type_str[(state)])48 49#define MHI_INVALID_BRSTMODE(mode) (mode != MHI_DB_BRST_DISABLE && \50				    mode != MHI_DB_BRST_ENABLE)51 52#define MHI_EE_LIST						\53	mhi_ee(PBL,			"PRIMARY BOOTLOADER")	\54	mhi_ee(SBL,			"SECONDARY BOOTLOADER")	\55	mhi_ee(AMSS,			"MISSION MODE")		\56	mhi_ee(RDDM,			"RAMDUMP DOWNLOAD MODE")\57	mhi_ee(WFW,			"WLAN FIRMWARE")	\58	mhi_ee(PTHRU,			"PASS THROUGH")		\59	mhi_ee(EDL,			"EMERGENCY DOWNLOAD")	\60	mhi_ee(FP,			"FLASH PROGRAMMER")	\61	mhi_ee(DISABLE_TRANSITION,	"DISABLE")		\62	mhi_ee_end(NOT_SUPPORTED,	"NOT SUPPORTED")63 64extern const char * const mhi_ee_str[MHI_EE_MAX];65#define TO_MHI_EXEC_STR(ee) (((ee) >= MHI_EE_MAX) ? \66			     "INVALID_EE" : mhi_ee_str[ee])67 68#define MHI_IN_PBL(ee) (ee == MHI_EE_PBL || ee == MHI_EE_PTHRU || \69			ee == MHI_EE_EDL)70#define MHI_POWER_UP_CAPABLE(ee) (MHI_IN_PBL(ee) || ee == MHI_EE_AMSS)71#define MHI_FW_LOAD_CAPABLE(ee) (ee == MHI_EE_PBL || ee == MHI_EE_EDL)72#define MHI_IN_MISSION_MODE(ee) (ee == MHI_EE_AMSS || ee == MHI_EE_WFW || \73				 ee == MHI_EE_FP)74 75enum dev_st_transition {76	DEV_ST_TRANSITION_PBL,77	DEV_ST_TRANSITION_READY,78	DEV_ST_TRANSITION_SBL,79	DEV_ST_TRANSITION_MISSION_MODE,80	DEV_ST_TRANSITION_FP,81	DEV_ST_TRANSITION_SYS_ERR,82	DEV_ST_TRANSITION_DISABLE,83	DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE,84	DEV_ST_TRANSITION_MAX,85};86 87#define DEV_ST_TRANSITION_LIST					\88	dev_st_trans(PBL,		"PBL")			\89	dev_st_trans(READY,		"READY")		\90	dev_st_trans(SBL,		"SBL")			\91	dev_st_trans(MISSION_MODE,	"MISSION MODE")		\92	dev_st_trans(FP,		"FLASH PROGRAMMER")	\93	dev_st_trans(SYS_ERR,		"SYS ERROR")		\94	dev_st_trans(DISABLE,		"DISABLE")		\95	dev_st_trans_end(DISABLE_DESTROY_DEVICE, "DISABLE (DESTROY DEVICE)")96 97extern const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX];98#define TO_DEV_STATE_TRANS_STR(state) (((state) >= DEV_ST_TRANSITION_MAX) ? \99				"INVALID_STATE" : dev_state_tran_str[state])100 101/* internal power states */102enum mhi_pm_state {103	MHI_PM_STATE_DISABLE,104	MHI_PM_STATE_POR,105	MHI_PM_STATE_M0,106	MHI_PM_STATE_M2,107	MHI_PM_STATE_M3_ENTER,108	MHI_PM_STATE_M3,109	MHI_PM_STATE_M3_EXIT,110	MHI_PM_STATE_FW_DL_ERR,111	MHI_PM_STATE_SYS_ERR_DETECT,112	MHI_PM_STATE_SYS_ERR_PROCESS,113	MHI_PM_STATE_SYS_ERR_FAIL,114	MHI_PM_STATE_SHUTDOWN_PROCESS,115	MHI_PM_STATE_LD_ERR_FATAL_DETECT,116	MHI_PM_STATE_MAX117};118 119#define MHI_PM_STATE_LIST							\120	mhi_pm_state(DISABLE,			"DISABLE")			\121	mhi_pm_state(POR,			"POWER ON RESET")		\122	mhi_pm_state(M0,			"M0")				\123	mhi_pm_state(M2,			"M2")				\124	mhi_pm_state(M3_ENTER,			"M?->M3")			\125	mhi_pm_state(M3,			"M3")				\126	mhi_pm_state(M3_EXIT,			"M3->M0")			\127	mhi_pm_state(FW_DL_ERR,			"Firmware Download Error")	\128	mhi_pm_state(SYS_ERR_DETECT,		"SYS ERROR Detect")		\129	mhi_pm_state(SYS_ERR_PROCESS,		"SYS ERROR Process")		\130	mhi_pm_state(SYS_ERR_FAIL,		"SYS ERROR Failure")		\131	mhi_pm_state(SHUTDOWN_PROCESS,		"SHUTDOWN Process")		\132	mhi_pm_state_end(LD_ERR_FATAL_DETECT,	"Linkdown or Error Fatal Detect")133 134#define MHI_PM_DISABLE					BIT(0)135#define MHI_PM_POR					BIT(1)136#define MHI_PM_M0					BIT(2)137#define MHI_PM_M2					BIT(3)138#define MHI_PM_M3_ENTER					BIT(4)139#define MHI_PM_M3					BIT(5)140#define MHI_PM_M3_EXIT					BIT(6)141/* firmware download failure state */142#define MHI_PM_FW_DL_ERR				BIT(7)143#define MHI_PM_SYS_ERR_DETECT				BIT(8)144#define MHI_PM_SYS_ERR_PROCESS				BIT(9)145#define MHI_PM_SYS_ERR_FAIL				BIT(10)146#define MHI_PM_SHUTDOWN_PROCESS				BIT(11)147/* link not accessible */148#define MHI_PM_LD_ERR_FATAL_DETECT			BIT(12)149 150#define MHI_REG_ACCESS_VALID(pm_state)			((pm_state & (MHI_PM_POR | MHI_PM_M0 | \151						MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \152						MHI_PM_SYS_ERR_DETECT | MHI_PM_SYS_ERR_PROCESS | \153						MHI_PM_SYS_ERR_FAIL | MHI_PM_SHUTDOWN_PROCESS |  \154						MHI_PM_FW_DL_ERR)))155#define MHI_PM_IN_ERROR_STATE(pm_state)			(pm_state >= MHI_PM_FW_DL_ERR)156#define MHI_PM_IN_FATAL_STATE(pm_state)			(pm_state == MHI_PM_LD_ERR_FATAL_DETECT)157#define MHI_DB_ACCESS_VALID(mhi_cntrl)			(mhi_cntrl->pm_state & mhi_cntrl->db_access)158#define MHI_WAKE_DB_CLEAR_VALID(pm_state)		(pm_state & (MHI_PM_M0 | \159							MHI_PM_M2 | MHI_PM_M3_EXIT))160#define MHI_WAKE_DB_SET_VALID(pm_state)			(pm_state & MHI_PM_M2)161#define MHI_WAKE_DB_FORCE_SET_VALID(pm_state)		MHI_WAKE_DB_CLEAR_VALID(pm_state)162#define MHI_EVENT_ACCESS_INVALID(pm_state)		(pm_state == MHI_PM_DISABLE || \163							MHI_PM_IN_ERROR_STATE(pm_state))164#define MHI_PM_IN_SUSPEND_STATE(pm_state)		(pm_state & \165							(MHI_PM_M3_ENTER | MHI_PM_M3))166 167#define NR_OF_CMD_RINGS					1168#define CMD_EL_PER_RING					128169#define PRIMARY_CMD_RING				0170#define MHI_DEV_WAKE_DB					127171#define MHI_MAX_MTU					0xffff172#define MHI_RANDOM_U32_NONZERO(bmsk)			(get_random_u32_inclusive(1, bmsk))173 174enum mhi_er_type {175	MHI_ER_TYPE_INVALID = 0x0,176	MHI_ER_TYPE_VALID = 0x1,177};178 179struct db_cfg {180	bool reset_req;181	bool db_mode;182	u32 pollcfg;183	enum mhi_db_brst_mode brstmode;184	dma_addr_t db_val;185	void (*process_db)(struct mhi_controller *mhi_cntrl,186			   struct db_cfg *db_cfg, void __iomem *io_addr,187			   dma_addr_t db_val);188};189 190struct mhi_pm_transitions {191	enum mhi_pm_state from_state;192	u32 to_states;193};194 195struct state_transition {196	struct list_head node;197	enum dev_st_transition state;198};199 200struct mhi_ring {201	dma_addr_t dma_handle;202	dma_addr_t iommu_base;203	__le64 *ctxt_wp; /* point to ctxt wp */204	void *pre_aligned;205	void *base;206	void *rp;207	void *wp;208	size_t el_size;209	size_t len;210	size_t elements;211	size_t alloc_size;212	void __iomem *db_addr;213};214 215struct mhi_cmd {216	struct mhi_ring ring;217	spinlock_t lock;218};219 220struct mhi_buf_info {221	void *v_addr;222	void *bb_addr;223	void *wp;224	void *cb_buf;225	dma_addr_t p_addr;226	size_t len;227	enum dma_data_direction dir;228	bool used; /* Indicates whether the buffer is used or not */229	bool pre_mapped; /* Already pre-mapped by client */230};231 232struct mhi_event {233	struct mhi_controller *mhi_cntrl;234	struct mhi_chan *mhi_chan; /* dedicated to channel */235	u32 er_index;236	u32 intmod;237	u32 irq;238	int chan; /* this event ring is dedicated to a channel (optional) */239	u32 priority;240	enum mhi_er_data_type data_type;241	struct mhi_ring ring;242	struct db_cfg db_cfg;243	struct tasklet_struct task;244	spinlock_t lock;245	int (*process_event)(struct mhi_controller *mhi_cntrl,246			     struct mhi_event *mhi_event,247			     u32 event_quota);248	bool hw_ring;249	bool cl_manage;250	bool offload_ev; /* managed by a device driver */251};252 253struct mhi_chan {254	const char *name;255	/*256	 * Important: When consuming, increment tre_ring first and when257	 * releasing, decrement buf_ring first. If tre_ring has space, buf_ring258	 * is guranteed to have space so we do not need to check both rings.259	 */260	struct mhi_ring buf_ring;261	struct mhi_ring tre_ring;262	u32 chan;263	u32 er_index;264	u32 intmod;265	enum mhi_ch_type type;266	enum dma_data_direction dir;267	struct db_cfg db_cfg;268	enum mhi_ch_ee_mask ee_mask;269	enum mhi_ch_state ch_state;270	enum mhi_ev_ccs ccs;271	struct mhi_device *mhi_dev;272	void (*xfer_cb)(struct mhi_device *mhi_dev, struct mhi_result *result);273	struct mutex mutex;274	struct completion completion;275	rwlock_t lock;276	struct list_head node;277	bool lpm_notify;278	bool configured;279	bool offload_ch;280	bool pre_alloc;281	bool wake_capable;282};283 284/* Default MHI timeout */285#define MHI_TIMEOUT_MS (1000)286 287/* debugfs related functions */288#ifdef CONFIG_MHI_BUS_DEBUG289void mhi_create_debugfs(struct mhi_controller *mhi_cntrl);290void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl);291void mhi_debugfs_init(void);292void mhi_debugfs_exit(void);293#else294static inline void mhi_create_debugfs(struct mhi_controller *mhi_cntrl)295{296}297 298static inline void mhi_destroy_debugfs(struct mhi_controller *mhi_cntrl)299{300}301 302static inline void mhi_debugfs_init(void)303{304}305 306static inline void mhi_debugfs_exit(void)307{308}309#endif310 311struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl);312 313int mhi_destroy_device(struct device *dev, void *data);314void mhi_create_devices(struct mhi_controller *mhi_cntrl);315 316int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,317			 struct image_info **image_info, size_t alloc_size);318void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,319			 struct image_info *image_info);320 321/* Power management APIs */322enum mhi_pm_state __must_check mhi_tryset_pm_state(323					struct mhi_controller *mhi_cntrl,324					enum mhi_pm_state state);325const char *to_mhi_pm_state_str(u32 state);326int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl,327			       enum dev_st_transition state);328void mhi_pm_st_worker(struct work_struct *work);329void mhi_pm_sys_err_handler(struct mhi_controller *mhi_cntrl);330int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl);331int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl);332void mhi_pm_m1_transition(struct mhi_controller *mhi_cntrl);333int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl);334int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl);335int mhi_send_cmd(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,336		 enum mhi_cmd_type cmd);337int mhi_download_amss_image(struct mhi_controller *mhi_cntrl);338static inline bool mhi_is_active(struct mhi_controller *mhi_cntrl)339{340	return (mhi_cntrl->dev_state >= MHI_STATE_M0 &&341		mhi_cntrl->dev_state <= MHI_STATE_M3_FAST);342}343 344static inline void mhi_trigger_resume(struct mhi_controller *mhi_cntrl)345{346	pm_wakeup_event(&mhi_cntrl->mhi_dev->dev, 0);347	mhi_cntrl->runtime_get(mhi_cntrl);348	mhi_cntrl->runtime_put(mhi_cntrl);349}350 351/* Register access methods */352void mhi_db_brstmode(struct mhi_controller *mhi_cntrl, struct db_cfg *db_cfg,353		     void __iomem *db_addr, dma_addr_t db_val);354void mhi_db_brstmode_disable(struct mhi_controller *mhi_cntrl,355			     struct db_cfg *db_mode, void __iomem *db_addr,356			     dma_addr_t db_val);357int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl,358			      void __iomem *base, u32 offset, u32 *out);359int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl,360				    void __iomem *base, u32 offset, u32 mask,361				    u32 *out);362int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,363				    void __iomem *base, u32 offset, u32 mask,364				    u32 val, u32 delayus, u32 timeout_ms);365void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,366		   u32 offset, u32 val);367int __must_check mhi_write_reg_field(struct mhi_controller *mhi_cntrl,368				     void __iomem *base, u32 offset, u32 mask,369				     u32 val);370void mhi_ring_er_db(struct mhi_event *mhi_event);371void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr,372		  dma_addr_t db_val);373void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd);374void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl,375		      struct mhi_chan *mhi_chan);376 377/* Initialization methods */378int mhi_init_mmio(struct mhi_controller *mhi_cntrl);379int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl);380void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl);381int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl);382void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl);383int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,384		      struct image_info *img_info);385void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl);386 387/* Automatically allocate and queue inbound buffers */388#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0)389int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,390			struct mhi_chan *mhi_chan, unsigned int flags);391 392int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,393		       struct mhi_chan *mhi_chan);394void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,395			  struct mhi_chan *mhi_chan);396void mhi_reset_chan(struct mhi_controller *mhi_cntrl,397		    struct mhi_chan *mhi_chan);398 399/* Event processing methods */400void mhi_ctrl_ev_task(unsigned long data);401void mhi_ev_task(unsigned long data);402int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,403				struct mhi_event *mhi_event, u32 event_quota);404int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,405			     struct mhi_event *mhi_event, u32 event_quota);406 407/* ISR handlers */408irqreturn_t mhi_irq_handler(int irq_number, void *dev);409irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *dev);410irqreturn_t mhi_intvec_handler(int irq_number, void *dev);411 412int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,413		struct mhi_buf_info *info, enum mhi_flags flags);414int mhi_map_single_no_bb(struct mhi_controller *mhi_cntrl,415			 struct mhi_buf_info *buf_info);416int mhi_map_single_use_bb(struct mhi_controller *mhi_cntrl,417			  struct mhi_buf_info *buf_info);418void mhi_unmap_single_no_bb(struct mhi_controller *mhi_cntrl,419			    struct mhi_buf_info *buf_info);420void mhi_unmap_single_use_bb(struct mhi_controller *mhi_cntrl,421			     struct mhi_buf_info *buf_info);422 423#endif /* _MHI_INT_H */424