1a4080225SVenkat Gopalakrishnan /* Copyright (c) 2015, The Linux Foundation. All rights reserved. 2a4080225SVenkat Gopalakrishnan * 3a4080225SVenkat Gopalakrishnan * This program is free software; you can redistribute it and/or modify 4a4080225SVenkat Gopalakrishnan * it under the terms of the GNU General Public License version 2 and 5a4080225SVenkat Gopalakrishnan * only version 2 as published by the Free Software Foundation. 6a4080225SVenkat Gopalakrishnan * 7a4080225SVenkat Gopalakrishnan * This program is distributed in the hope that it will be useful, 8a4080225SVenkat Gopalakrishnan * but WITHOUT ANY WARRANTY; without even the implied warranty of 9a4080225SVenkat Gopalakrishnan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10a4080225SVenkat Gopalakrishnan * GNU General Public License for more details. 11a4080225SVenkat Gopalakrishnan */ 12a4080225SVenkat Gopalakrishnan #ifndef LINUX_MMC_CQHCI_H 13a4080225SVenkat Gopalakrishnan #define LINUX_MMC_CQHCI_H 14a4080225SVenkat Gopalakrishnan 15a4080225SVenkat Gopalakrishnan #include <linux/compiler.h> 16a4080225SVenkat Gopalakrishnan #include <linux/bitops.h> 17a4080225SVenkat Gopalakrishnan #include <linux/spinlock_types.h> 18a4080225SVenkat Gopalakrishnan #include <linux/types.h> 19a4080225SVenkat Gopalakrishnan #include <linux/completion.h> 20a4080225SVenkat Gopalakrishnan #include <linux/wait.h> 21a4080225SVenkat Gopalakrishnan #include <linux/irqreturn.h> 22a4080225SVenkat Gopalakrishnan #include <asm/io.h> 23a4080225SVenkat Gopalakrishnan 24a4080225SVenkat Gopalakrishnan /* registers */ 25a4080225SVenkat Gopalakrishnan /* version */ 26a4080225SVenkat Gopalakrishnan #define CQHCI_VER 0x00 27a4080225SVenkat Gopalakrishnan #define CQHCI_VER_MAJOR(x) (((x) & GENMASK(11, 8)) >> 8) 28a4080225SVenkat Gopalakrishnan #define CQHCI_VER_MINOR1(x) (((x) & GENMASK(7, 4)) >> 4) 29a4080225SVenkat Gopalakrishnan #define CQHCI_VER_MINOR2(x) ((x) & GENMASK(3, 0)) 30a4080225SVenkat Gopalakrishnan 31a4080225SVenkat Gopalakrishnan /* capabilities */ 32a4080225SVenkat Gopalakrishnan #define CQHCI_CAP 0x04 33a4080225SVenkat Gopalakrishnan /* configuration */ 34a4080225SVenkat Gopalakrishnan #define CQHCI_CFG 0x08 35a4080225SVenkat Gopalakrishnan #define CQHCI_DCMD 0x00001000 36a4080225SVenkat Gopalakrishnan #define CQHCI_TASK_DESC_SZ 0x00000100 37a4080225SVenkat Gopalakrishnan #define CQHCI_ENABLE 0x00000001 38a4080225SVenkat Gopalakrishnan 39a4080225SVenkat Gopalakrishnan /* control */ 40a4080225SVenkat Gopalakrishnan #define CQHCI_CTL 0x0C 41a4080225SVenkat Gopalakrishnan #define CQHCI_CLEAR_ALL_TASKS 0x00000100 42a4080225SVenkat Gopalakrishnan #define CQHCI_HALT 0x00000001 43a4080225SVenkat Gopalakrishnan 44a4080225SVenkat Gopalakrishnan /* interrupt status */ 45a4080225SVenkat Gopalakrishnan #define CQHCI_IS 0x10 46a4080225SVenkat Gopalakrishnan #define CQHCI_IS_HAC BIT(0) 47a4080225SVenkat Gopalakrishnan #define CQHCI_IS_TCC BIT(1) 48a4080225SVenkat Gopalakrishnan #define CQHCI_IS_RED BIT(2) 49a4080225SVenkat Gopalakrishnan #define CQHCI_IS_TCL BIT(3) 50a4080225SVenkat Gopalakrishnan 51a4080225SVenkat Gopalakrishnan #define CQHCI_IS_MASK (CQHCI_IS_TCC | CQHCI_IS_RED) 52a4080225SVenkat Gopalakrishnan 53a4080225SVenkat Gopalakrishnan /* interrupt status enable */ 54a4080225SVenkat Gopalakrishnan #define CQHCI_ISTE 0x14 55a4080225SVenkat Gopalakrishnan 56a4080225SVenkat Gopalakrishnan /* interrupt signal enable */ 57a4080225SVenkat Gopalakrishnan #define CQHCI_ISGE 0x18 58a4080225SVenkat Gopalakrishnan 59a4080225SVenkat Gopalakrishnan /* interrupt coalescing */ 60a4080225SVenkat Gopalakrishnan #define CQHCI_IC 0x1C 61a4080225SVenkat Gopalakrishnan #define CQHCI_IC_ENABLE BIT(31) 62a4080225SVenkat Gopalakrishnan #define CQHCI_IC_RESET BIT(16) 63a4080225SVenkat Gopalakrishnan #define CQHCI_IC_ICCTHWEN BIT(15) 640562315bSAdrian Hunter #define CQHCI_IC_ICCTH(x) (((x) & 0x1F) << 8) 65a4080225SVenkat Gopalakrishnan #define CQHCI_IC_ICTOVALWEN BIT(7) 660562315bSAdrian Hunter #define CQHCI_IC_ICTOVAL(x) ((x) & 0x7F) 67a4080225SVenkat Gopalakrishnan 68a4080225SVenkat Gopalakrishnan /* task list base address */ 69a4080225SVenkat Gopalakrishnan #define CQHCI_TDLBA 0x20 70a4080225SVenkat Gopalakrishnan 71a4080225SVenkat Gopalakrishnan /* task list base address upper */ 72a4080225SVenkat Gopalakrishnan #define CQHCI_TDLBAU 0x24 73a4080225SVenkat Gopalakrishnan 74a4080225SVenkat Gopalakrishnan /* door-bell */ 75a4080225SVenkat Gopalakrishnan #define CQHCI_TDBR 0x28 76a4080225SVenkat Gopalakrishnan 77a4080225SVenkat Gopalakrishnan /* task completion notification */ 78a4080225SVenkat Gopalakrishnan #define CQHCI_TCN 0x2C 79a4080225SVenkat Gopalakrishnan 80a4080225SVenkat Gopalakrishnan /* device queue status */ 81a4080225SVenkat Gopalakrishnan #define CQHCI_DQS 0x30 82a4080225SVenkat Gopalakrishnan 83a4080225SVenkat Gopalakrishnan /* device pending tasks */ 84a4080225SVenkat Gopalakrishnan #define CQHCI_DPT 0x34 85a4080225SVenkat Gopalakrishnan 86a4080225SVenkat Gopalakrishnan /* task clear */ 87a4080225SVenkat Gopalakrishnan #define CQHCI_TCLR 0x38 88a4080225SVenkat Gopalakrishnan 89a4080225SVenkat Gopalakrishnan /* send status config 1 */ 90a4080225SVenkat Gopalakrishnan #define CQHCI_SSC1 0x40 9168895644SSowjanya Komatineni #define CQHCI_SSC1_CBC_MASK GENMASK(19, 16) 92a4080225SVenkat Gopalakrishnan 93a4080225SVenkat Gopalakrishnan /* send status config 2 */ 94a4080225SVenkat Gopalakrishnan #define CQHCI_SSC2 0x44 95a4080225SVenkat Gopalakrishnan 96a4080225SVenkat Gopalakrishnan /* response for dcmd */ 97a4080225SVenkat Gopalakrishnan #define CQHCI_CRDCT 0x48 98a4080225SVenkat Gopalakrishnan 99a4080225SVenkat Gopalakrishnan /* response mode error mask */ 100a4080225SVenkat Gopalakrishnan #define CQHCI_RMEM 0x50 101a4080225SVenkat Gopalakrishnan 102a4080225SVenkat Gopalakrishnan /* task error info */ 103a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI 0x54 104a4080225SVenkat Gopalakrishnan 105a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI_C_INDEX(x) ((x) & GENMASK(5, 0)) 106a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI_C_TASK(x) (((x) & GENMASK(12, 8)) >> 8) 107a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI_C_VALID(x) ((x) & BIT(15)) 108a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI_D_INDEX(x) (((x) & GENMASK(21, 16)) >> 16) 109a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI_D_TASK(x) (((x) & GENMASK(28, 24)) >> 24) 110a4080225SVenkat Gopalakrishnan #define CQHCI_TERRI_D_VALID(x) ((x) & BIT(31)) 111a4080225SVenkat Gopalakrishnan 112a4080225SVenkat Gopalakrishnan /* command response index */ 113a4080225SVenkat Gopalakrishnan #define CQHCI_CRI 0x58 114a4080225SVenkat Gopalakrishnan 115a4080225SVenkat Gopalakrishnan /* command response argument */ 116a4080225SVenkat Gopalakrishnan #define CQHCI_CRA 0x5C 117a4080225SVenkat Gopalakrishnan 118a4080225SVenkat Gopalakrishnan #define CQHCI_INT_ALL 0xF 119a4080225SVenkat Gopalakrishnan #define CQHCI_IC_DEFAULT_ICCTH 31 120a4080225SVenkat Gopalakrishnan #define CQHCI_IC_DEFAULT_ICTOVAL 1 121a4080225SVenkat Gopalakrishnan 122a4080225SVenkat Gopalakrishnan /* attribute fields */ 1230562315bSAdrian Hunter #define CQHCI_VALID(x) (((x) & 1) << 0) 1240562315bSAdrian Hunter #define CQHCI_END(x) (((x) & 1) << 1) 1250562315bSAdrian Hunter #define CQHCI_INT(x) (((x) & 1) << 2) 1260562315bSAdrian Hunter #define CQHCI_ACT(x) (((x) & 0x7) << 3) 127a4080225SVenkat Gopalakrishnan 128a4080225SVenkat Gopalakrishnan /* data command task descriptor fields */ 1290562315bSAdrian Hunter #define CQHCI_FORCED_PROG(x) (((x) & 1) << 6) 1300562315bSAdrian Hunter #define CQHCI_CONTEXT(x) (((x) & 0xF) << 7) 1310562315bSAdrian Hunter #define CQHCI_DATA_TAG(x) (((x) & 1) << 11) 1320562315bSAdrian Hunter #define CQHCI_DATA_DIR(x) (((x) & 1) << 12) 1330562315bSAdrian Hunter #define CQHCI_PRIORITY(x) (((x) & 1) << 13) 1340562315bSAdrian Hunter #define CQHCI_QBAR(x) (((x) & 1) << 14) 1350562315bSAdrian Hunter #define CQHCI_REL_WRITE(x) (((x) & 1) << 15) 1360562315bSAdrian Hunter #define CQHCI_BLK_COUNT(x) (((x) & 0xFFFF) << 16) 1370562315bSAdrian Hunter #define CQHCI_BLK_ADDR(x) (((x) & 0xFFFFFFFF) << 32) 138a4080225SVenkat Gopalakrishnan 139a4080225SVenkat Gopalakrishnan /* direct command task descriptor fields */ 1400562315bSAdrian Hunter #define CQHCI_CMD_INDEX(x) (((x) & 0x3F) << 16) 1410562315bSAdrian Hunter #define CQHCI_CMD_TIMING(x) (((x) & 1) << 22) 1420562315bSAdrian Hunter #define CQHCI_RESP_TYPE(x) (((x) & 0x3) << 23) 143a4080225SVenkat Gopalakrishnan 144a4080225SVenkat Gopalakrishnan /* transfer descriptor fields */ 1450562315bSAdrian Hunter #define CQHCI_DAT_LENGTH(x) (((x) & 0xFFFF) << 16) 1460562315bSAdrian Hunter #define CQHCI_DAT_ADDR_LO(x) (((x) & 0xFFFFFFFF) << 32) 1470562315bSAdrian Hunter #define CQHCI_DAT_ADDR_HI(x) (((x) & 0xFFFFFFFF) << 0) 148a4080225SVenkat Gopalakrishnan 149a4080225SVenkat Gopalakrishnan struct cqhci_host_ops; 150a4080225SVenkat Gopalakrishnan struct mmc_host; 151c46d089aSSowjanya Komatineni struct mmc_request; 152a4080225SVenkat Gopalakrishnan struct cqhci_slot; 153a4080225SVenkat Gopalakrishnan 154a4080225SVenkat Gopalakrishnan struct cqhci_host { 155a4080225SVenkat Gopalakrishnan const struct cqhci_host_ops *ops; 156a4080225SVenkat Gopalakrishnan void __iomem *mmio; 157a4080225SVenkat Gopalakrishnan struct mmc_host *mmc; 158a4080225SVenkat Gopalakrishnan 159a4080225SVenkat Gopalakrishnan spinlock_t lock; 160a4080225SVenkat Gopalakrishnan 161a4080225SVenkat Gopalakrishnan /* relative card address of device */ 162a4080225SVenkat Gopalakrishnan unsigned int rca; 163a4080225SVenkat Gopalakrishnan 164a4080225SVenkat Gopalakrishnan /* 64 bit DMA */ 165a4080225SVenkat Gopalakrishnan bool dma64; 166a4080225SVenkat Gopalakrishnan int num_slots; 167a4080225SVenkat Gopalakrishnan int qcnt; 168a4080225SVenkat Gopalakrishnan 169a4080225SVenkat Gopalakrishnan u32 dcmd_slot; 170a4080225SVenkat Gopalakrishnan u32 caps; 171a4080225SVenkat Gopalakrishnan #define CQHCI_TASK_DESC_SZ_128 0x1 172a4080225SVenkat Gopalakrishnan 173a4080225SVenkat Gopalakrishnan u32 quirks; 174a4080225SVenkat Gopalakrishnan #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ 0x1 175a4080225SVenkat Gopalakrishnan 176a4080225SVenkat Gopalakrishnan bool enabled; 177a4080225SVenkat Gopalakrishnan bool halted; 178a4080225SVenkat Gopalakrishnan bool init_done; 179a4080225SVenkat Gopalakrishnan bool activated; 180a4080225SVenkat Gopalakrishnan bool waiting_for_idle; 181a4080225SVenkat Gopalakrishnan bool recovery_halt; 182a4080225SVenkat Gopalakrishnan 183a4080225SVenkat Gopalakrishnan size_t desc_size; 184a4080225SVenkat Gopalakrishnan size_t data_size; 185a4080225SVenkat Gopalakrishnan 186a4080225SVenkat Gopalakrishnan u8 *desc_base; 187a4080225SVenkat Gopalakrishnan 188a4080225SVenkat Gopalakrishnan /* total descriptor size */ 189a4080225SVenkat Gopalakrishnan u8 slot_sz; 190a4080225SVenkat Gopalakrishnan 191a4080225SVenkat Gopalakrishnan /* 64/128 bit depends on CQHCI_CFG */ 192a4080225SVenkat Gopalakrishnan u8 task_desc_len; 193a4080225SVenkat Gopalakrishnan 194a4080225SVenkat Gopalakrishnan /* 64 bit on 32-bit arch, 128 bit on 64-bit */ 195a4080225SVenkat Gopalakrishnan u8 link_desc_len; 196a4080225SVenkat Gopalakrishnan 197a4080225SVenkat Gopalakrishnan u8 *trans_desc_base; 198a4080225SVenkat Gopalakrishnan /* same length as transfer descriptor */ 199a4080225SVenkat Gopalakrishnan u8 trans_desc_len; 200a4080225SVenkat Gopalakrishnan 201a4080225SVenkat Gopalakrishnan dma_addr_t desc_dma_base; 202a4080225SVenkat Gopalakrishnan dma_addr_t trans_desc_dma_base; 203a4080225SVenkat Gopalakrishnan 204a4080225SVenkat Gopalakrishnan struct completion halt_comp; 205a4080225SVenkat Gopalakrishnan wait_queue_head_t wait_queue; 206a4080225SVenkat Gopalakrishnan struct cqhci_slot *slot; 207a4080225SVenkat Gopalakrishnan }; 208a4080225SVenkat Gopalakrishnan 209a4080225SVenkat Gopalakrishnan struct cqhci_host_ops { 210a4080225SVenkat Gopalakrishnan void (*dumpregs)(struct mmc_host *mmc); 211a4080225SVenkat Gopalakrishnan void (*write_l)(struct cqhci_host *host, u32 val, int reg); 212a4080225SVenkat Gopalakrishnan u32 (*read_l)(struct cqhci_host *host, int reg); 213a4080225SVenkat Gopalakrishnan void (*enable)(struct mmc_host *mmc); 214a4080225SVenkat Gopalakrishnan void (*disable)(struct mmc_host *mmc, bool recovery); 215c46d089aSSowjanya Komatineni void (*update_dcmd_desc)(struct mmc_host *mmc, struct mmc_request *mrq, 216c46d089aSSowjanya Komatineni u64 *data); 217a4080225SVenkat Gopalakrishnan }; 218a4080225SVenkat Gopalakrishnan 219a4080225SVenkat Gopalakrishnan static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg) 220a4080225SVenkat Gopalakrishnan { 221a4080225SVenkat Gopalakrishnan if (unlikely(host->ops->write_l)) 222a4080225SVenkat Gopalakrishnan host->ops->write_l(host, val, reg); 223a4080225SVenkat Gopalakrishnan else 224a4080225SVenkat Gopalakrishnan writel_relaxed(val, host->mmio + reg); 225a4080225SVenkat Gopalakrishnan } 226a4080225SVenkat Gopalakrishnan 227a4080225SVenkat Gopalakrishnan static inline u32 cqhci_readl(struct cqhci_host *host, int reg) 228a4080225SVenkat Gopalakrishnan { 229a4080225SVenkat Gopalakrishnan if (unlikely(host->ops->read_l)) 230a4080225SVenkat Gopalakrishnan return host->ops->read_l(host, reg); 231a4080225SVenkat Gopalakrishnan else 232a4080225SVenkat Gopalakrishnan return readl_relaxed(host->mmio + reg); 233a4080225SVenkat Gopalakrishnan } 234a4080225SVenkat Gopalakrishnan 235a4080225SVenkat Gopalakrishnan struct platform_device; 236a4080225SVenkat Gopalakrishnan 237a4080225SVenkat Gopalakrishnan irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error, 238a4080225SVenkat Gopalakrishnan int data_error); 239a4080225SVenkat Gopalakrishnan int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64); 240a4080225SVenkat Gopalakrishnan struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev); 241a4080225SVenkat Gopalakrishnan int cqhci_suspend(struct mmc_host *mmc); 242a4080225SVenkat Gopalakrishnan int cqhci_resume(struct mmc_host *mmc); 243a4080225SVenkat Gopalakrishnan 244a4080225SVenkat Gopalakrishnan #endif 245