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 ||
|