blob: 1aabce98d199dc933df31457601512c00b0231b0 [file] [log] [blame]
Sahitya Tummala02b59422015-05-06 10:41:16 +05301/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#ifndef LINUX_MMC_CQ_HCI_H
13#define LINUX_MMC_CQ_HCI_H
14#include <linux/mmc/core.h>
15
16/* registers */
17/* version */
18#define CQVER 0x00
19/* capabilities */
20#define CQCAP 0x04
Veerabhadrarao Badiganti87ddf1b2016-12-11 20:16:58 +053021#define CQCAP_CS (1 << 28)
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -070022/* configuration */
23#define CQCFG 0x08
24#define CQ_DCMD 0x00001000
25#define CQ_TASK_DESC_SZ 0x00000100
26#define CQ_ENABLE 0x00000001
Veerabhadrarao Badiganti87ddf1b2016-12-11 20:16:58 +053027#define CQ_ICE_ENABLE 0x00000002
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -070028
29/* control */
30#define CQCTL 0x0C
31#define CLEAR_ALL_TASKS 0x00000100
32#define HALT 0x00000001
33
34/* interrupt status */
35#define CQIS 0x10
36#define CQIS_HAC (1 << 0)
37#define CQIS_TCC (1 << 1)
38#define CQIS_RED (1 << 2)
39#define CQIS_TCL (1 << 3)
Veerabhadrarao Badigantib6782992016-12-11 20:38:20 +053040#define CQIS_GCE (1 << 4)
41#define CQIS_ICCE (1 << 5)
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -070042
43/* interrupt status enable */
44#define CQISTE 0x14
45
46/* interrupt signal enable */
47#define CQISGE 0x18
48
49/* interrupt coalescing */
50#define CQIC 0x1C
51#define CQIC_ENABLE (1 << 31)
52#define CQIC_RESET (1 << 16)
53#define CQIC_ICCTHWEN (1 << 15)
54#define CQIC_ICCTH(x) ((x & 0x1F) << 8)
55#define CQIC_ICTOVALWEN (1 << 7)
56#define CQIC_ICTOVAL(x) (x & 0x7F)
57
58/* task list base address */
59#define CQTDLBA 0x20
60
61/* task list base address upper */
62#define CQTDLBAU 0x24
63
64/* door-bell */
65#define CQTDBR 0x28
66
67/* task completion notification */
68#define CQTCN 0x2C
69
70/* device queue status */
71#define CQDQS 0x30
72
73/* device pending tasks */
74#define CQDPT 0x34
75
76/* task clear */
77#define CQTCLR 0x38
78
79/* send status config 1 */
80#define CQSSC1 0x40
81/*
82 * Value n means CQE would send CMD13 during the transfer of data block
83 * BLOCK_CNT-n
84 */
Asutosh Das5b81f132015-10-06 09:53:33 +053085#define SEND_QSR_INTERVAL 0x70001
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -070086
87/* send status config 2 */
88#define CQSSC2 0x44
89
90/* response for dcmd */
91#define CQCRDCT 0x48
92
93/* response mode error mask */
94#define CQRMEM 0x50
Dov Levenglick2b678302015-07-01 14:24:20 +030095#define CQ_EXCEPTION (1 << 6)
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -070096
97/* task error info */
98#define CQTERRI 0x54
99
Asutosh Das02e30862015-05-20 16:52:04 +0530100/* CQTERRI bit fields */
101#define CQ_RMECI 0x1F
102#define CQ_RMETI (0x1F << 8)
103#define CQ_RMEFV (1 << 15)
104#define CQ_DTECI (0x3F << 16)
105#define CQ_DTETI (0x1F << 24)
106#define CQ_DTEFV (1 << 31)
107
108#define GET_CMD_ERR_TAG(__r__) ((__r__ & CQ_RMETI) >> 8)
109#define GET_DAT_ERR_TAG(__r__) ((__r__ & CQ_DTETI) >> 24)
110
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700111/* command response index */
112#define CQCRI 0x58
113
114/* command response argument */
115#define CQCRA 0x5C
116
Veerabhadrarao Badigantib6782992016-12-11 20:38:20 +0530117#define CQ_INT_ALL 0x3F
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700118#define CQIC_DEFAULT_ICCTH 31
119#define CQIC_DEFAULT_ICTOVAL 1
120
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700121/* attribute fields */
122#define VALID(x) ((x & 1) << 0)
123#define END(x) ((x & 1) << 1)
124#define INT(x) ((x & 1) << 2)
125#define ACT(x) ((x & 0x7) << 3)
126
127/* data command task descriptor fields */
128#define FORCED_PROG(x) ((x & 1) << 6)
129#define CONTEXT(x) ((x & 0xF) << 7)
130#define DATA_TAG(x) ((x & 1) << 11)
131#define DATA_DIR(x) ((x & 1) << 12)
132#define PRIORITY(x) ((x & 1) << 13)
133#define QBAR(x) ((x & 1) << 14)
134#define REL_WRITE(x) ((x & 1) << 15)
135#define BLK_COUNT(x) ((x & 0xFFFF) << 16)
136#define BLK_ADDR(x) ((x & 0xFFFFFFFF) << 32)
137
138/* direct command task descriptor fields */
139#define CMD_INDEX(x) ((x & 0x3F) << 16)
140#define CMD_TIMING(x) ((x & 1) << 22)
141#define RESP_TYPE(x) ((x & 0x3) << 23)
142
143/* transfer descriptor fields */
144#define DAT_LENGTH(x) ((x & 0xFFFF) << 16)
145#define DAT_ADDR_LO(x) ((x & 0xFFFFFFFF) << 32)
146#define DAT_ADDR_HI(x) ((x & 0xFFFFFFFF) << 0)
147
Sayali Lokhande6e7e6d52017-01-04 12:00:35 +0530148/*
149 * Add new macro for updated CQ vendor specific
150 * register address for SDHC v5.0 onwards.
151 */
152#define CQ_V5_VENDOR_CFG 0x900
Asutosh Dasc0ed9c42015-05-29 15:39:37 +0530153#define CQ_VENDOR_CFG 0x100
154#define CMDQ_SEND_STATUS_TRIGGER (1 << 31)
155
Veerabhadrarao Badiganti87ddf1b2016-12-11 20:16:58 +0530156#define CQ_TASK_DESC_TASK_PARAMS_SIZE 8
157#define CQ_TASK_DESC_ICE_PARAMS_SIZE 8
158
Venkat Gopalakrishnane77c64d2015-09-28 18:53:18 -0700159struct task_history {
160 u64 task;
161 bool is_dcmd;
162};
163
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700164struct cmdq_host {
165 const struct cmdq_host_ops *ops;
166 void __iomem *mmio;
167 struct mmc_host *mmc;
168
169 /* 64 bit DMA */
170 bool dma64;
171 int num_slots;
172
173 u32 dcmd_slot;
174 u32 caps;
175#define CMDQ_TASK_DESC_SZ_128 0x1
Veerabhadrarao Badiganti87ddf1b2016-12-11 20:16:58 +0530176#define CMDQ_CAP_CRYPTO_SUPPORT 0x2
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700177
178 u32 quirks;
179#define CMDQ_QUIRK_SHORT_TXFR_DESC_SZ 0x1
180#define CMDQ_QUIRK_NO_DCMD 0x2
181
182 bool enabled;
183 bool halted;
184 bool init_done;
Sayali Lokhande6e7e6d52017-01-04 12:00:35 +0530185 bool offset_changed;
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700186
187 u8 *desc_base;
188
189 /* total descriptor size */
190 u8 slot_sz;
191
192 /* 64/128 bit depends on CQCFG */
193 u8 task_desc_len;
194
195 /* 64 bit on 32-bit arch, 128 bit on 64-bit */
196 u8 link_desc_len;
197
198 u8 *trans_desc_base;
199 /* same length as transfer descriptor */
200 u8 trans_desc_len;
201
202 dma_addr_t desc_dma_base;
203 dma_addr_t trans_desc_dma_base;
204
Venkat Gopalakrishnane77c64d2015-09-28 18:53:18 -0700205 struct task_history *thist;
206 u8 thist_idx;
207
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700208 struct completion halt_comp;
209 struct mmc_request **mrq_slot;
210 void *private;
211};
212
213struct cmdq_host_ops {
Sahitya Tummala87231ce2016-04-12 13:24:51 +0530214 void (*set_transfer_params)(struct mmc_host *mmc);
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700215 void (*set_data_timeout)(struct mmc_host *mmc, u32 val);
216 void (*clear_set_irqs)(struct mmc_host *mmc, bool clear);
217 void (*set_block_size)(struct mmc_host *mmc);
218 void (*dump_vendor_regs)(struct mmc_host *mmc);
219 void (*write_l)(struct cmdq_host *host, u32 val, int reg);
220 u32 (*read_l)(struct cmdq_host *host, int reg);
221 void (*clear_set_dumpregs)(struct mmc_host *mmc, bool set);
Ritesh Harjani6b2ea572015-07-15 13:23:05 +0530222 void (*enhanced_strobe_mask)(struct mmc_host *mmc, bool set);
Asutosh Das02e30862015-05-20 16:52:04 +0530223 int (*reset)(struct mmc_host *mmc);
Konstantin Dorfmanfa321072015-05-31 10:10:13 +0300224 void (*post_cqe_halt)(struct mmc_host *mmc);
Sahitya Tummala02b59422015-05-06 10:41:16 +0530225 int (*crypto_cfg)(struct mmc_host *mmc, struct mmc_request *mrq,
Veerabhadrarao Badiganti87ddf1b2016-12-11 20:16:58 +0530226 u32 slot, u64 *ice_ctx);
Veerabhadrarao Badiganti57056d52017-03-08 07:04:10 +0530227 int (*crypto_cfg_end)(struct mmc_host *mmc, struct mmc_request *mrq);
Sahitya Tummala82a19752015-09-01 16:44:08 +0530228 void (*crypto_cfg_reset)(struct mmc_host *mmc, unsigned int slot);
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700229};
230
231static inline void cmdq_writel(struct cmdq_host *host, u32 val, int reg)
232{
Ritesh Harjaniee93d262015-12-30 15:53:49 +0530233 if (unlikely(host->ops && host->ops->write_l))
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700234 host->ops->write_l(host, val, reg);
235 else
236 writel_relaxed(val, host->mmio + reg);
237}
238
239static inline u32 cmdq_readl(struct cmdq_host *host, int reg)
240{
Ritesh Harjaniee93d262015-12-30 15:53:49 +0530241 if (unlikely(host->ops && host->ops->read_l))
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700242 return host->ops->read_l(host, reg);
243 else
244 return readl_relaxed(host->mmio + reg);
245}
246
Asutosh Das02e30862015-05-20 16:52:04 +0530247extern irqreturn_t cmdq_irq(struct mmc_host *mmc, int err);
Venkat Gopalakrishnan0225ff92015-05-29 17:25:46 -0700248extern int cmdq_init(struct cmdq_host *cq_host, struct mmc_host *mmc,
249 bool dma64);
250extern struct cmdq_host *cmdq_pltfm_init(struct platform_device *pdev);
251#endif