mirror of https://github.com/OpenIPC/firmware.git
				
				
				
			
		
			
				
	
	
		
			201 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Diff
		
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Diff
		
	
	
| --- linux-4.9.37/include/linux/mmc/host.h	2017-07-12 16:42:41.000000000 +0300
 | |
| +++ linux-4.9.y/include/linux/mmc/host.h	2021-06-07 13:01:34.000000000 +0300
 | |
| @@ -82,6 +82,17 @@
 | |
|  	bool enhanced_strobe;			/* hs400es selection */
 | |
|  };
 | |
|  
 | |
| +struct mmc_cmdq_host_ops {
 | |
| +	int (*init)(struct mmc_host *host);
 | |
| +	int (*enable)(struct mmc_host *host);
 | |
| +	void (*disable)(struct mmc_host *host, bool soft);
 | |
| +	int (*request)(struct mmc_host *host, struct mmc_request *mrq);
 | |
| +	void (*post_req)(struct mmc_host *host, int tag, int err);
 | |
| +	int (*halt)(struct mmc_host *host, bool halt);
 | |
| +	void (*reset)(struct mmc_host *host, bool soft);
 | |
| +	void (*dumpstate)(struct mmc_host *host);
 | |
| +};
 | |
| +
 | |
|  struct mmc_host_ops {
 | |
|  	/*
 | |
|  	 * It is optional for the host to implement pre_req and post_req in
 | |
| @@ -161,11 +172,37 @@
 | |
|  	 */
 | |
|  	int	(*multi_io_quirk)(struct mmc_card *card,
 | |
|  				  unsigned int direction, int blk_size);
 | |
| +	void	(*notify_halt)(struct mmc_host *mmc, bool halt);
 | |
| +	int     (*card_info_save)(struct mmc_host *host);
 | |
|  };
 | |
|  
 | |
|  struct mmc_card;
 | |
|  struct device;
 | |
|  
 | |
| +struct mmc_cmdq_req {
 | |
| +	unsigned int cmd_flags;
 | |
| +	u32 blk_addr;
 | |
| +	/* active mmc request */
 | |
| +	struct mmc_request	mrq;
 | |
| +	struct mmc_data		data;
 | |
| +	struct mmc_command	cmd;
 | |
| +#define DCMD		(1 << 0)
 | |
| +#define QBR		(1 << 1)
 | |
| +#define DIR		(1 << 2)
 | |
| +#define PRIO		(1 << 3)
 | |
| +#define REL_WR		(1 << 4)
 | |
| +#define DAT_TAG	(1 << 5)
 | |
| +#define FORCED_PRG	(1 << 6)
 | |
| +	unsigned int		cmdq_req_flags;
 | |
| +
 | |
| +	unsigned int		resp_idx;
 | |
| +	unsigned int		resp_arg;
 | |
| +	unsigned int		dev_pend_tasks;
 | |
| +	bool			resp_err;
 | |
| +	int			tag; /* used for command queuing */
 | |
| +	u8			ctx_id;
 | |
| +};
 | |
| +
 | |
|  struct mmc_async_req {
 | |
|  	/* active mmc request */
 | |
|  	struct mmc_request	*mrq;
 | |
| @@ -192,6 +229,33 @@
 | |
|  	void *handler_priv;
 | |
|  };
 | |
|  
 | |
| +
 | |
| +/**
 | |
| + * mmc_cmdq_context_info - describes the contexts of cmdq
 | |
| + * @active_reqs		requests being processed
 | |
| + * @data_active_reqs	data requests being processed
 | |
| + * @curr_state		state of cmdq engine
 | |
| + * @cmdq_ctx_lock	acquire this before accessing this structure
 | |
| + * @queue_empty_wq	workqueue for waiting for all
 | |
| + *			the outstanding requests to be completed
 | |
| + * @wait		waiting for all conditions described in
 | |
| + *			mmc_cmdq_ready_wait to be satisified before
 | |
| + *			issuing the new request to LLD.
 | |
| + */
 | |
| +struct mmc_cmdq_context_info {
 | |
| +	unsigned long	active_reqs; /* in-flight requests */
 | |
| +	unsigned long	data_active_reqs; /* in-flight data requests */
 | |
| +	unsigned long	curr_state;
 | |
| +#define	CMDQ_STATE_ERR 0
 | |
| +#define	CMDQ_STATE_DCMD_ACTIVE 1
 | |
| +#define	CMDQ_STATE_HALT 2
 | |
| +#define	CMDQ_STATE_CQ_DISABLE 3
 | |
| +#define	CMDQ_STATE_REQ_TIMED_OUT 4
 | |
| +	wait_queue_head_t	queue_empty_wq;
 | |
| +	wait_queue_head_t	wait;
 | |
| +	int active_small_sector_read_reqs;
 | |
| +};
 | |
| +
 | |
|  /**
 | |
|   * mmc_context_info - synchronization details for mmc context
 | |
|   * @is_done_rcv		wake up reason was done request
 | |
| @@ -221,10 +285,17 @@
 | |
|  	struct device		class_dev;
 | |
|  	int			index;
 | |
|  	const struct mmc_host_ops *ops;
 | |
| +	const struct mmc_cmdq_host_ops *cmdq_ops;
 | |
|  	struct mmc_pwrseq	*pwrseq;
 | |
|  	unsigned int		f_min;
 | |
|  	unsigned int		f_max;
 | |
|  	unsigned int		f_init;
 | |
| +	unsigned int		type;
 | |
| +#define MMC_HOST_TYPE_MMC		0		/* MMC card */
 | |
| +#define MMC_HOST_TYPE_SD		1		/* SD card */
 | |
| +#define MMC_HOST_TYPE_SDIO		2		/* SDIO card */
 | |
| +#define MMC_HOST_TYPE_SD_COMBO		3		/* SD combo (IO+mem) card */
 | |
| +
 | |
|  	u32			ocr_avail;
 | |
|  	u32			ocr_avail_sdio;	/* SDIO-specific OCR */
 | |
|  	u32			ocr_avail_sd;	/* SD-specific OCR */
 | |
| @@ -312,6 +383,7 @@
 | |
|  #define MMC_CAP2_HS400_ES	(1 << 20)	/* Host supports enhanced strobe */
 | |
|  #define MMC_CAP2_NO_SD		(1 << 21)	/* Do not send SD commands during initialization */
 | |
|  #define MMC_CAP2_NO_MMC		(1 << 22)	/* Do not send (e)MMC commands during initialization */
 | |
| +#define MMC_CAP2_CMD_QUEUE	(1 << 23)	/* support eMMC command queue */
 | |
|  
 | |
|  	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 | |
|  
 | |
| @@ -359,6 +431,11 @@
 | |
|  
 | |
|  	struct delayed_work	detect;
 | |
|  	int			detect_change;	/* card detect flag */
 | |
| +	u32			card_status;
 | |
| +#define MMC_CARD_UNINIT		0
 | |
| +#define MMC_CARD_INIT		1
 | |
| +#define MMC_CARD_INIT_FAIL	2
 | |
| +
 | |
|  	struct mmc_slot		slot;
 | |
|  
 | |
|  	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 | |
| @@ -397,6 +474,20 @@
 | |
|  	int			dsr_req;	/* DSR value is valid */
 | |
|  	u32			dsr;	/* optional driver stage (DSR) value */
 | |
|  
 | |
| +	struct mmc_cmdq_context_info	cmdq_ctx;
 | |
| +	int num_cq_slots;
 | |
| +	int dcmd_cq_slot;
 | |
| +	u32			cmdq_thist_enabled;
 | |
| +	/*
 | |
| +	 * several cmdq supporting host controllers are extensions
 | |
| +	 * of legacy controllers. This variable can be used to store
 | |
| +	 * a reference to the cmdq extension of the existing host
 | |
| +	 * controller.
 | |
| +	 */
 | |
| +	void *cmdq_private;
 | |
| +	struct mmc_request	*err_mrq;
 | |
| +	struct timeval start;
 | |
| +	struct timeval end;
 | |
|  	unsigned long		private[0] ____cacheline_aligned;
 | |
|  };
 | |
|  
 | |
| @@ -411,6 +502,11 @@
 | |
|  	return (void *)host->private;
 | |
|  }
 | |
|  
 | |
| +static inline void *mmc_cmdq_private(struct mmc_host *host)
 | |
| +{
 | |
| +	return host->cmdq_private;
 | |
| +}
 | |
| +
 | |
|  #define mmc_host_is_spi(host)	((host)->caps & MMC_CAP_SPI)
 | |
|  
 | |
|  #define mmc_dev(x)	((x)->parent)
 | |
| @@ -500,6 +596,36 @@
 | |
|  	return host->caps2 & MMC_CAP2_PACKED_WR;
 | |
|  }
 | |
|  
 | |
| +static inline void mmc_host_set_halt(struct mmc_host *host)
 | |
| +{
 | |
| +	set_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
 | |
| +}
 | |
| +
 | |
| +static inline void mmc_host_clr_halt(struct mmc_host *host)
 | |
| +{
 | |
| +	clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
 | |
| +}
 | |
| +
 | |
| +static inline int mmc_host_halt(struct mmc_host *host)
 | |
| +{
 | |
| +	return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
 | |
| +}
 | |
| +
 | |
| +static inline void mmc_host_set_cq_disable(struct mmc_host *host)
 | |
| +{
 | |
| +	set_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state);
 | |
| +}
 | |
| +
 | |
| +static inline void mmc_host_clr_cq_disable(struct mmc_host *host)
 | |
| +{
 | |
| +	clear_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state);
 | |
| +}
 | |
| +
 | |
| +static inline int mmc_host_cq_disable(struct mmc_host *host)
 | |
| +{
 | |
| +	return test_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state);
 | |
| +}
 | |
| +
 | |
|  static inline int mmc_card_hs(struct mmc_card *card)
 | |
|  {
 | |
|  	return card->host->ios.timing == MMC_TIMING_SD_HS ||
 |