1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Synopsys DesignWare Multimedia Card Interface driver 3*4882a593Smuzhiyun * (Based on NXP driver for lpc 31xx) 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2009 NXP Semiconductors 6*4882a593Smuzhiyun * Copyright (C) 2009, 2010 Imagination Technologies Ltd. 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (C) 2014 Fuzhou Rockchip Electronics Co.Ltd. 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify 11*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published by 12*4882a593Smuzhiyun * the Free Software Foundation; either version 2 of the License, or 13*4882a593Smuzhiyun * (at your option) any later version. 14*4882a593Smuzhiyun */ 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #ifndef _DW_MMC_H_ 17*4882a593Smuzhiyun #define _DW_MMC_H_ 18*4882a593Smuzhiyun #include "rk_sdmmc_dbg.h" 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #define DW_MMC_240A 0x240a 21*4882a593Smuzhiyun #define DW_MMC_270A 0x270a 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #define SDMMC_CTRL 0x000 24*4882a593Smuzhiyun #define SDMMC_PWREN 0x004 25*4882a593Smuzhiyun #define SDMMC_CLKDIV 0x008 26*4882a593Smuzhiyun #define SDMMC_CLKSRC 0x00c 27*4882a593Smuzhiyun #define SDMMC_CLKENA 0x010 28*4882a593Smuzhiyun #define SDMMC_TMOUT 0x014 29*4882a593Smuzhiyun #define SDMMC_CTYPE 0x018 30*4882a593Smuzhiyun #define SDMMC_BLKSIZ 0x01c 31*4882a593Smuzhiyun #define SDMMC_BYTCNT 0x020 32*4882a593Smuzhiyun #define SDMMC_INTMASK 0x024 33*4882a593Smuzhiyun #define SDMMC_CMDARG 0x028 34*4882a593Smuzhiyun #define SDMMC_CMD 0x02c 35*4882a593Smuzhiyun #define SDMMC_RESP0 0x030 36*4882a593Smuzhiyun #define SDMMC_RESP1 0x034 37*4882a593Smuzhiyun #define SDMMC_RESP2 0x038 38*4882a593Smuzhiyun #define SDMMC_RESP3 0x03c 39*4882a593Smuzhiyun #define SDMMC_MINTSTS 0x040 40*4882a593Smuzhiyun #define SDMMC_RINTSTS 0x044 41*4882a593Smuzhiyun #define SDMMC_STATUS 0x048 42*4882a593Smuzhiyun #define SDMMC_FIFOTH 0x04c 43*4882a593Smuzhiyun #define SDMMC_CDETECT 0x050 44*4882a593Smuzhiyun #define SDMMC_WRTPRT 0x054 45*4882a593Smuzhiyun #define SDMMC_GPIO 0x058 46*4882a593Smuzhiyun #define SDMMC_TCBCNT 0x05c 47*4882a593Smuzhiyun #define SDMMC_TBBCNT 0x060 48*4882a593Smuzhiyun #define SDMMC_DEBNCE 0x064 49*4882a593Smuzhiyun #define SDMMC_USRID 0x068 50*4882a593Smuzhiyun #define SDMMC_VERID 0x06c 51*4882a593Smuzhiyun #define SDMMC_HCON 0x070 52*4882a593Smuzhiyun #define SDMMC_UHS_REG 0x074 53*4882a593Smuzhiyun #define SDMMC_RST_N 0x078 54*4882a593Smuzhiyun #define SDMMC_BMOD 0x080 55*4882a593Smuzhiyun #define SDMMC_PLDMND 0x084 56*4882a593Smuzhiyun #define SDMMC_DBADDR 0x088 57*4882a593Smuzhiyun #define SDMMC_IDSTS 0x08c 58*4882a593Smuzhiyun #define SDMMC_IDINTEN 0x090 59*4882a593Smuzhiyun #define SDMMC_DSCADDR 0x094 60*4882a593Smuzhiyun #define SDMMC_BUFADDR 0x098 61*4882a593Smuzhiyun #define SDMMC_CDTHRCTL 0x100 62*4882a593Smuzhiyun #define SDMMC_DATA(x) (x) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun static const u8 tuning_blk_pattern_4bit[] = { 66*4882a593Smuzhiyun 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 67*4882a593Smuzhiyun 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 68*4882a593Smuzhiyun 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 69*4882a593Smuzhiyun 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 70*4882a593Smuzhiyun 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 71*4882a593Smuzhiyun 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 72*4882a593Smuzhiyun 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 73*4882a593Smuzhiyun 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, 74*4882a593Smuzhiyun }; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun static const u8 tuning_blk_pattern_8bit[] = { 77*4882a593Smuzhiyun 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 78*4882a593Smuzhiyun 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 79*4882a593Smuzhiyun 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 80*4882a593Smuzhiyun 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 81*4882a593Smuzhiyun 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 82*4882a593Smuzhiyun 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 83*4882a593Smuzhiyun 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 84*4882a593Smuzhiyun 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 85*4882a593Smuzhiyun 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 86*4882a593Smuzhiyun 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 87*4882a593Smuzhiyun 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 88*4882a593Smuzhiyun 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 89*4882a593Smuzhiyun 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 90*4882a593Smuzhiyun 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 91*4882a593Smuzhiyun 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 92*4882a593Smuzhiyun 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 93*4882a593Smuzhiyun }; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun /* 96*4882a593Smuzhiyun * Data offset is difference according to Version 97*4882a593Smuzhiyun * Lower than 2.40a : data register offest is 0x100 98*4882a593Smuzhiyun */ 99*4882a593Smuzhiyun #define DATA_OFFSET 0x100 100*4882a593Smuzhiyun #define DATA_240A_OFFSET 0x200 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* shift bit field */ 103*4882a593Smuzhiyun #define _SBF(f, v) ((v) << (f)) 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun struct sdmmc_reg { 107*4882a593Smuzhiyun u32 addr; 108*4882a593Smuzhiyun char *name; 109*4882a593Smuzhiyun }; 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun static const struct sdmmc_reg dw_mci_regs[] = { 112*4882a593Smuzhiyun { 0x0000, "CTRL" }, 113*4882a593Smuzhiyun { 0x0004, "PWREN" }, 114*4882a593Smuzhiyun { 0x0008, "CLKDIV" }, 115*4882a593Smuzhiyun { 0x000C, "CLKSRC" }, 116*4882a593Smuzhiyun { 0x0010, "CLKENA" }, 117*4882a593Smuzhiyun { 0x0014, "TMOUT" }, 118*4882a593Smuzhiyun { 0x0018, "CTYPE" }, 119*4882a593Smuzhiyun { 0x001C, "BLKSIZ" }, 120*4882a593Smuzhiyun { 0x0020, "BYTCNT" }, 121*4882a593Smuzhiyun { 0x0024, "INTMASK" }, 122*4882a593Smuzhiyun { 0x0028, "CMDARG" }, 123*4882a593Smuzhiyun { 0x002C, "CMD" }, 124*4882a593Smuzhiyun { 0x0030, "RESP0" }, 125*4882a593Smuzhiyun { 0x0034, "RESP1" }, 126*4882a593Smuzhiyun { 0x0038, "RESP2" }, 127*4882a593Smuzhiyun { 0x003C, "RESP3" }, 128*4882a593Smuzhiyun { 0x0040, "MINSTS" }, 129*4882a593Smuzhiyun { 0x0044, "RINTSTS" }, 130*4882a593Smuzhiyun { 0x0048, "STATUS" }, 131*4882a593Smuzhiyun { 0x004C, "FIFOTH" }, 132*4882a593Smuzhiyun { 0x0050, "CDETECT" }, 133*4882a593Smuzhiyun { 0x0054, "WRTPRT" }, 134*4882a593Smuzhiyun { 0x0058, "GPIO" }, 135*4882a593Smuzhiyun { 0x005C, "TCBCNT" }, 136*4882a593Smuzhiyun { 0x0060, "TBBCNT" }, 137*4882a593Smuzhiyun { 0x0064, "DEBNCE" }, 138*4882a593Smuzhiyun { 0x0068, "USRID" }, 139*4882a593Smuzhiyun { 0x006C, "VERID" }, 140*4882a593Smuzhiyun { 0x0070, "HCON" }, 141*4882a593Smuzhiyun { 0x0074, "UHS_REG" }, 142*4882a593Smuzhiyun { 0x0078, "RST_n" }, 143*4882a593Smuzhiyun { 0x0080, "BMOD" }, 144*4882a593Smuzhiyun { 0x0084, "PLDMND" }, 145*4882a593Smuzhiyun { 0x0088, "DBADDR" }, 146*4882a593Smuzhiyun { 0x008C, "IDSTS" }, 147*4882a593Smuzhiyun { 0x0090, "IDINTEN" }, 148*4882a593Smuzhiyun { 0x0094, "DSCADDR" }, 149*4882a593Smuzhiyun { 0x0098, "BUFADDR" }, 150*4882a593Smuzhiyun { 0x0100, "CARDTHRCTL" }, 151*4882a593Smuzhiyun { 0x0104, "BackEndPwr" }, 152*4882a593Smuzhiyun { 0, 0 } 153*4882a593Smuzhiyun }; 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun /* Control register defines */ 157*4882a593Smuzhiyun #define SDMMC_CTRL_USE_IDMAC BIT(25) 158*4882a593Smuzhiyun #define SDMMC_CTRL_CEATA_INT_EN BIT(11) 159*4882a593Smuzhiyun #define SDMMC_CTRL_SEND_AS_CCSD BIT(10) 160*4882a593Smuzhiyun #define SDMMC_CTRL_SEND_CCSD BIT(9) 161*4882a593Smuzhiyun #define SDMMC_CTRL_ABRT_READ_DATA BIT(8) 162*4882a593Smuzhiyun #define SDMMC_CTRL_SEND_IRQ_RESP BIT(7) 163*4882a593Smuzhiyun #define SDMMC_CTRL_READ_WAIT BIT(6) 164*4882a593Smuzhiyun #define SDMMC_CTRL_DMA_ENABLE BIT(5) 165*4882a593Smuzhiyun #define SDMMC_CTRL_INT_ENABLE BIT(4) 166*4882a593Smuzhiyun #define SDMMC_CTRL_DMA_RESET BIT(2) 167*4882a593Smuzhiyun #define SDMMC_CTRL_FIFO_RESET BIT(1) 168*4882a593Smuzhiyun #define SDMMC_CTRL_RESET BIT(0) 169*4882a593Smuzhiyun /* Clock Enable register defines */ 170*4882a593Smuzhiyun #define SDMMC_CLKEN_LOW_PWR BIT(16) 171*4882a593Smuzhiyun #define SDMMC_CLKEN_ENABLE BIT(0) 172*4882a593Smuzhiyun /* time-out register defines */ 173*4882a593Smuzhiyun #define SDMMC_TMOUT_DATA(n) _SBF(8, (n)) 174*4882a593Smuzhiyun #define SDMMC_TMOUT_DATA_MSK 0xFFFFFF00 175*4882a593Smuzhiyun #define SDMMC_TMOUT_RESP(n) ((n) & 0xFF) 176*4882a593Smuzhiyun #define SDMMC_TMOUT_RESP_MSK 0xFF 177*4882a593Smuzhiyun /* card-type register defines */ 178*4882a593Smuzhiyun #define SDMMC_CTYPE_8BIT BIT(16) 179*4882a593Smuzhiyun #define SDMMC_CTYPE_4BIT BIT(0) 180*4882a593Smuzhiyun #define SDMMC_CTYPE_1BIT 0 181*4882a593Smuzhiyun /* Interrupt status & mask register defines */ 182*4882a593Smuzhiyun #define SDMMC_INT_SDIO(n) BIT(16 + (n)) 183*4882a593Smuzhiyun #define SDMMC_INT_EBE BIT(15) 184*4882a593Smuzhiyun #define SDMMC_INT_ACD BIT(14) 185*4882a593Smuzhiyun #define SDMMC_INT_SBE BIT(13) 186*4882a593Smuzhiyun #define SDMMC_INT_HLE BIT(12) 187*4882a593Smuzhiyun #define SDMMC_INT_FRUN BIT(11) 188*4882a593Smuzhiyun #define SDMMC_INT_HTO BIT(10) 189*4882a593Smuzhiyun #define SDMMC_INT_VSI SDMMC_INT_HTO 190*4882a593Smuzhiyun #define SDMMC_INT_DRTO BIT(9) 191*4882a593Smuzhiyun #define SDMMC_INT_RTO BIT(8) 192*4882a593Smuzhiyun #define SDMMC_INT_DCRC BIT(7) 193*4882a593Smuzhiyun #define SDMMC_INT_RCRC BIT(6) 194*4882a593Smuzhiyun #define SDMMC_INT_RXDR BIT(5) 195*4882a593Smuzhiyun #define SDMMC_INT_TXDR BIT(4) 196*4882a593Smuzhiyun #define SDMMC_INT_DATA_OVER BIT(3) 197*4882a593Smuzhiyun #define SDMMC_INT_CMD_DONE BIT(2) 198*4882a593Smuzhiyun #define SDMMC_INT_RESP_ERR BIT(1) 199*4882a593Smuzhiyun #define SDMMC_INT_CD BIT(0) 200*4882a593Smuzhiyun #define SDMMC_INT_ERROR 0xbfc2 201*4882a593Smuzhiyun /* Command register defines */ 202*4882a593Smuzhiyun #define SDMMC_CMD_START BIT(31) 203*4882a593Smuzhiyun #define SDMMC_CMD_USE_HOLD_REG BIT(29) 204*4882a593Smuzhiyun #define SDMMC_CMD_VOLT_SWITCH BIT(28) 205*4882a593Smuzhiyun #define SDMMC_CMD_BOOT_MODE BIT(27) 206*4882a593Smuzhiyun #define SDMMC_CMD_DISABLE_BOOT BIT(26) 207*4882a593Smuzhiyun #define SDMMC_CMD_EXPECT_BOOT_ACK BIT(25) 208*4882a593Smuzhiyun #define SDMMC_CMD_ENABLE_BOOT BIT(24) 209*4882a593Smuzhiyun #define SDMMC_CMD_CCS_EXP BIT(23) 210*4882a593Smuzhiyun #define SDMMC_CMD_CEATA_RD BIT(22) 211*4882a593Smuzhiyun #define SDMMC_CMD_UPD_CLK BIT(21) 212*4882a593Smuzhiyun #define SDMMC_CMD_INIT BIT(15) 213*4882a593Smuzhiyun #define SDMMC_CMD_STOP BIT(14) 214*4882a593Smuzhiyun #define SDMMC_CMD_PRV_DAT_WAIT BIT(13) 215*4882a593Smuzhiyun #define SDMMC_CMD_SEND_STOP BIT(12) 216*4882a593Smuzhiyun #define SDMMC_CMD_STRM_MODE BIT(11) 217*4882a593Smuzhiyun #define SDMMC_CMD_DAT_WR BIT(10) 218*4882a593Smuzhiyun #define SDMMC_CMD_DAT_EXP BIT(9) 219*4882a593Smuzhiyun #define SDMMC_CMD_RESP_CRC BIT(8) 220*4882a593Smuzhiyun #define SDMMC_CMD_RESP_LONG BIT(7) 221*4882a593Smuzhiyun #define SDMMC_CMD_RESP_EXP BIT(6) 222*4882a593Smuzhiyun #define SDMMC_CMD_INDX(n) ((n) & 0x1F) 223*4882a593Smuzhiyun /* Status register defines */ 224*4882a593Smuzhiyun #define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FFF) 225*4882a593Smuzhiyun #define SDMMC_STAUTS_MC_BUSY BIT(10) 226*4882a593Smuzhiyun #define SDMMC_STAUTS_DATA_BUSY BIT(9) 227*4882a593Smuzhiyun #define SDMMC_CMD_FSM_MASK (0x0F << 4) 228*4882a593Smuzhiyun #define SDMMC_CMD_FSM_IDLE (0x00) 229*4882a593Smuzhiyun #define SDMMC_STAUTS_FIFO_FULL BIT(3) 230*4882a593Smuzhiyun #define SDMMC_STAUTS_FIFO_EMPTY BIT(2) 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun /* Control SDMMC_UHS_REG defines (base+ 0x74)*/ 233*4882a593Smuzhiyun #define SDMMC_UHS_DDR_MODE BIT(16) 234*4882a593Smuzhiyun #define SDMMC_UHS_VOLT_REG_18 BIT(0) 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun /* FIFOTH register defines */ 237*4882a593Smuzhiyun #define SDMMC_SET_FIFOTH(m, r, t) (((m) & 0x7) << 28 | \ 238*4882a593Smuzhiyun ((r) & 0xFFF) << 16 | \ 239*4882a593Smuzhiyun ((t) & 0xFFF)) 240*4882a593Smuzhiyun /* Internal DMAC interrupt defines */ 241*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_AI BIT(9) 242*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_NI BIT(8) 243*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_CES BIT(5) 244*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_DU BIT(4) 245*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_FBE BIT(2) 246*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_RI BIT(1) 247*4882a593Smuzhiyun #define SDMMC_IDMAC_INT_TI BIT(0) 248*4882a593Smuzhiyun /* Internal DMAC bus mode bits */ 249*4882a593Smuzhiyun #define SDMMC_IDMAC_ENABLE BIT(7) 250*4882a593Smuzhiyun #define SDMMC_IDMAC_FB BIT(1) 251*4882a593Smuzhiyun #define SDMMC_IDMAC_SWRESET BIT(0) 252*4882a593Smuzhiyun /* Version ID register define */ 253*4882a593Smuzhiyun #define SDMMC_GET_VERID(x) ((x) & 0xFFFF) 254*4882a593Smuzhiyun /* Card read threshold */ 255*4882a593Smuzhiyun #define SDMMC_SET_RD_THLD(v, x) (((v) & 0xFFF) << 16 | (x)) 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun /* Register access macros */ 258*4882a593Smuzhiyun #define mci_readl(dev, reg) \ 259*4882a593Smuzhiyun __raw_readl((dev)->regs + SDMMC_##reg) 260*4882a593Smuzhiyun #define mci_writel(dev, reg, value) \ 261*4882a593Smuzhiyun __raw_writel((value), (dev)->regs + SDMMC_##reg) 262*4882a593Smuzhiyun #define mci_readreg(dev, addr) \ 263*4882a593Smuzhiyun __raw_readl((dev)->regs + addr) 264*4882a593Smuzhiyun #define mci_writereg(dev, addr, value) \ 265*4882a593Smuzhiyun __raw_writel((value), (dev)->regs + addr) 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun /* 16-bit FIFO access macros */ 269*4882a593Smuzhiyun #define mci_readw(dev, reg) \ 270*4882a593Smuzhiyun __raw_readw((dev)->regs + SDMMC_##reg) 271*4882a593Smuzhiyun #define mci_writew(dev, reg, value) \ 272*4882a593Smuzhiyun __raw_writew((value), (dev)->regs + SDMMC_##reg) 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun /* 64-bit FIFO access macros */ 275*4882a593Smuzhiyun #ifdef readq 276*4882a593Smuzhiyun #define mci_readq(dev, reg) \ 277*4882a593Smuzhiyun __raw_readq((dev)->regs + SDMMC_##reg) 278*4882a593Smuzhiyun #define mci_writeq(dev, reg, value) \ 279*4882a593Smuzhiyun __raw_writeq((value), (dev)->regs + SDMMC_##reg) 280*4882a593Smuzhiyun #else 281*4882a593Smuzhiyun /* 282*4882a593Smuzhiyun * Dummy readq implementation for architectures that don't define it. 283*4882a593Smuzhiyun * 284*4882a593Smuzhiyun * We would assume that none of these architectures would configure 285*4882a593Smuzhiyun * the IP block with a 64bit FIFO width, so this code will never be 286*4882a593Smuzhiyun * executed on those machines. Defining these macros here keeps the 287*4882a593Smuzhiyun * rest of the code free from ifdefs. 288*4882a593Smuzhiyun */ 289*4882a593Smuzhiyun #define mci_readq(dev, reg) \ 290*4882a593Smuzhiyun (*(u64 __force *)((dev)->regs + SDMMC_##reg)) 291*4882a593Smuzhiyun #define mci_writeq(dev, reg, value) \ 292*4882a593Smuzhiyun (*(u64 __force *)((dev)->regs + SDMMC_##reg) = (value)) 293*4882a593Smuzhiyun #endif 294*4882a593Smuzhiyun #ifdef CONFIG_PM 295*4882a593Smuzhiyun extern int dw_mci_suspend(struct dw_mci *host); 296*4882a593Smuzhiyun extern int dw_mci_resume(struct dw_mci *host); 297*4882a593Smuzhiyun #endif 298*4882a593Smuzhiyun static const struct dw_mci_rst_ops dw_mci_pdrst_ops; 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun /** 301*4882a593Smuzhiyun * struct dw_mci_slot - MMC slot state 302*4882a593Smuzhiyun * @mmc: The mmc_host representing this slot. 303*4882a593Smuzhiyun * @host: The MMC controller this slot is using. 304*4882a593Smuzhiyun * @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX) 305*4882a593Smuzhiyun * @wp_gpio: If gpio_is_valid() we'll use this to read write protect. 306*4882a593Smuzhiyun * @ctype: Card type for this slot. 307*4882a593Smuzhiyun * @mrq: mmc_request currently being processed or waiting to be 308*4882a593Smuzhiyun * processed, or NULL when the slot is idle. 309*4882a593Smuzhiyun * @queue_node: List node for placing this node in the @queue list of 310*4882a593Smuzhiyun * &struct dw_mci. 311*4882a593Smuzhiyun * @clock: Clock rate configured by set_ios(). Protected by host->lock. 312*4882a593Smuzhiyun * @__clk_old: The last updated clock with reflecting clock divider. 313*4882a593Smuzhiyun * Keeping track of this helps us to avoid spamming the console 314*4882a593Smuzhiyun * with CONFIG_MMC_CLKGATE. 315*4882a593Smuzhiyun * @flags: Random state bits associated with the slot. 316*4882a593Smuzhiyun * @id: Number of this slot. 317*4882a593Smuzhiyun * @last_detect_state: Most recently observed card detect state. 318*4882a593Smuzhiyun */ 319*4882a593Smuzhiyun struct dw_mci_slot { 320*4882a593Smuzhiyun struct mmc_host *mmc; 321*4882a593Smuzhiyun struct dw_mci *host; 322*4882a593Smuzhiyun int quirks; 323*4882a593Smuzhiyun int wp_gpio; 324*4882a593Smuzhiyun int cd_gpio; 325*4882a593Smuzhiyun int pwr_en_gpio; 326*4882a593Smuzhiyun u32 ctype; 327*4882a593Smuzhiyun u32 pre_ctype; 328*4882a593Smuzhiyun 329*4882a593Smuzhiyun struct mmc_request *mrq; 330*4882a593Smuzhiyun struct list_head queue_node; 331*4882a593Smuzhiyun 332*4882a593Smuzhiyun unsigned int clock; 333*4882a593Smuzhiyun unsigned int __clk_old; 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun unsigned long flags; 336*4882a593Smuzhiyun #define DW_MMC_CARD_PRESENT 0 337*4882a593Smuzhiyun #define DW_MMC_CARD_NEED_INIT 1 338*4882a593Smuzhiyun int id; 339*4882a593Smuzhiyun int last_detect_state; 340*4882a593Smuzhiyun }; 341*4882a593Smuzhiyun 342*4882a593Smuzhiyun struct dw_mci_tuning_data { 343*4882a593Smuzhiyun const u8 *blk_pattern; 344*4882a593Smuzhiyun unsigned int blksz; 345*4882a593Smuzhiyun }; 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun /** 348*4882a593Smuzhiyun * dw_mci driver data - dw-mshc implementation specific driver data. 349*4882a593Smuzhiyun * @caps: mmc subsystem specified capabilities of the controller(s). 350*4882a593Smuzhiyun * @hold_reg_flag: Fixed the value of HOLG_REG 351*4882a593Smuzhiyun * @init: early implementation specific initialization. 352*4882a593Smuzhiyun * @setup_clock: implementation specific clock configuration. 353*4882a593Smuzhiyun * @prepare_command: handle CMD register extensions. 354*4882a593Smuzhiyun * @set_ios: handle bus specific extensions. 355*4882a593Smuzhiyun * @parse_dt: parse implementation specific device tree properties. 356*4882a593Smuzhiyun * 357*4882a593Smuzhiyun * Provide controller implementation specific extensions. The usage of this 358*4882a593Smuzhiyun * data structure is fully optional and usage of each member in this structure 359*4882a593Smuzhiyun * is optional as well. 360*4882a593Smuzhiyun */ 361*4882a593Smuzhiyun 362*4882a593Smuzhiyun struct dw_mci_drv_data { 363*4882a593Smuzhiyun unsigned long *caps; 364*4882a593Smuzhiyun unsigned int *hold_reg_flag; 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun int (*init)(struct dw_mci *host); 367*4882a593Smuzhiyun int (*setup_clock)(struct dw_mci *host); 368*4882a593Smuzhiyun void (*prepare_command)(struct dw_mci *host, u32 *cmdr); 369*4882a593Smuzhiyun void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); 370*4882a593Smuzhiyun int (*parse_dt)(struct dw_mci *host); 371*4882a593Smuzhiyun int (*execute_tuning)(struct dw_mci_slot *slot, 372*4882a593Smuzhiyun u32 opcode, 373*4882a593Smuzhiyun struct dw_mci_tuning_data 374*4882a593Smuzhiyun *tuning_data); 375*4882a593Smuzhiyun }; 376*4882a593Smuzhiyun 377*4882a593Smuzhiyun /* Variations in Rockchip specific dw-mshc controller */ 378*4882a593Smuzhiyun enum dw_mci_rockchip_type { 379*4882a593Smuzhiyun DW_MCI_TYPE_RK3188, 380*4882a593Smuzhiyun DW_MCI_TYPE_RK3288, 381*4882a593Smuzhiyun DW_MCI_TYPE_RK3036, 382*4882a593Smuzhiyun DW_MCI_TYPE_RK312X, 383*4882a593Smuzhiyun DW_MCI_TYPE_RK3368, 384*4882a593Smuzhiyun DW_MCI_TYPE_RK3228, 385*4882a593Smuzhiyun }; 386*4882a593Smuzhiyun 387*4882a593Smuzhiyun #endif /* _DW_MMC_H_ */ 388