11 #include <linux/pci.h>
12 #include <linux/module.h>
19 #define DRV_NAME "via_sdmmc"
21 #define PCI_DEVICE_ID_VIA_9530 0x9530
23 #define VIA_CRDR_SDC_OFF 0x200
24 #define VIA_CRDR_DDMA_OFF 0x400
25 #define VIA_CRDR_PCICTRL_OFF 0x600
27 #define VIA_CRDR_MIN_CLOCK 375000
28 #define VIA_CRDR_MAX_CLOCK 48000000
34 #define VIA_CRDR_PCI_WORK_MODE 0x40
35 #define VIA_CRDR_PCI_DBG_MODE 0x41
41 #define VIA_CRDR_SDCTRL 0x0
42 #define VIA_CRDR_SDCTRL_START 0x01
43 #define VIA_CRDR_SDCTRL_WRITE 0x04
44 #define VIA_CRDR_SDCTRL_SINGLE_WR 0x10
45 #define VIA_CRDR_SDCTRL_SINGLE_RD 0x20
46 #define VIA_CRDR_SDCTRL_MULTI_WR 0x30
47 #define VIA_CRDR_SDCTRL_MULTI_RD 0x40
48 #define VIA_CRDR_SDCTRL_STOP 0x70
50 #define VIA_CRDR_SDCTRL_RSP_NONE 0x0
51 #define VIA_CRDR_SDCTRL_RSP_R1 0x10000
52 #define VIA_CRDR_SDCTRL_RSP_R2 0x20000
53 #define VIA_CRDR_SDCTRL_RSP_R3 0x30000
54 #define VIA_CRDR_SDCTRL_RSP_R1B 0x90000
56 #define VIA_CRDR_SDCARG 0x4
58 #define VIA_CRDR_SDBUSMODE 0x8
59 #define VIA_CRDR_SDMODE_4BIT 0x02
60 #define VIA_CRDR_SDMODE_CLK_ON 0x40
62 #define VIA_CRDR_SDBLKLEN 0xc
70 #define VIA_CRDR_SDBLKLEN_GPIDET 0x2000
71 #define VIA_CRDR_SDBLKLEN_INTEN 0x8000
72 #define VIA_CRDR_MAX_BLOCK_COUNT 65536
73 #define VIA_CRDR_MAX_BLOCK_LENGTH 2048
75 #define VIA_CRDR_SDRESP0 0x10
76 #define VIA_CRDR_SDRESP1 0x14
77 #define VIA_CRDR_SDRESP2 0x18
78 #define VIA_CRDR_SDRESP3 0x1c
80 #define VIA_CRDR_SDCURBLKCNT 0x20
82 #define VIA_CRDR_SDINTMASK 0x24
95 #define VIA_CRDR_SDINTMASK_MBDIE 0x10
96 #define VIA_CRDR_SDINTMASK_BDDIE 0x20
97 #define VIA_CRDR_SDINTMASK_CIRIE 0x80
98 #define VIA_CRDR_SDINTMASK_CRDIE 0x200
99 #define VIA_CRDR_SDINTMASK_CRTOIE 0x400
100 #define VIA_CRDR_SDINTMASK_ASCRDIE 0x800
101 #define VIA_CRDR_SDINTMASK_DTIE 0x1000
102 #define VIA_CRDR_SDINTMASK_SCIE 0x2000
103 #define VIA_CRDR_SDINTMASK_RCIE 0x4000
104 #define VIA_CRDR_SDINTMASK_WCIE 0x8000
106 #define VIA_CRDR_SDACTIVE_INTMASK \
107 (VIA_CRDR_SDINTMASK_MBDIE | VIA_CRDR_SDINTMASK_CIRIE \
108 | VIA_CRDR_SDINTMASK_CRDIE | VIA_CRDR_SDINTMASK_CRTOIE \
109 | VIA_CRDR_SDINTMASK_DTIE | VIA_CRDR_SDINTMASK_SCIE \
110 | VIA_CRDR_SDINTMASK_RCIE | VIA_CRDR_SDINTMASK_WCIE)
112 #define VIA_CRDR_SDSTATUS 0x28
131 #define VIA_CRDR_SDSTS_CECC 0x01
132 #define VIA_CRDR_SDSTS_WP 0x02
133 #define VIA_CRDR_SDSTS_SLOTD 0x04
134 #define VIA_CRDR_SDSTS_SLOTG 0x08
135 #define VIA_CRDR_SDSTS_MBD 0x10
136 #define VIA_CRDR_SDSTS_BDD 0x20
137 #define VIA_CRDR_SDSTS_CD 0x40
138 #define VIA_CRDR_SDSTS_CIR 0x80
139 #define VIA_CRDR_SDSTS_IO 0x100
140 #define VIA_CRDR_SDSTS_CRD 0x200
141 #define VIA_CRDR_SDSTS_CRTO 0x400
142 #define VIA_CRDR_SDSTS_ASCRDIE 0x800
143 #define VIA_CRDR_SDSTS_DT 0x1000
144 #define VIA_CRDR_SDSTS_SC 0x2000
145 #define VIA_CRDR_SDSTS_RC 0x4000
146 #define VIA_CRDR_SDSTS_WC 0x8000
148 #define VIA_CRDR_SDSTS_IGN_MASK\
149 (VIA_CRDR_SDSTS_BDD | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_IO)
150 #define VIA_CRDR_SDSTS_INT_MASK \
151 (VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_BDD | VIA_CRDR_SDSTS_CD \
152 | VIA_CRDR_SDSTS_CIR | VIA_CRDR_SDSTS_IO | VIA_CRDR_SDSTS_CRD \
153 | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_DT \
154 | VIA_CRDR_SDSTS_SC | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)
155 #define VIA_CRDR_SDSTS_W1C_MASK \
156 (VIA_CRDR_SDSTS_CECC | VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_BDD \
157 | VIA_CRDR_SDSTS_CD | VIA_CRDR_SDSTS_CIR | VIA_CRDR_SDSTS_CRD \
158 | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_DT \
159 | VIA_CRDR_SDSTS_SC | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)
160 #define VIA_CRDR_SDSTS_CMD_MASK \
161 (VIA_CRDR_SDSTS_CRD | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_SC)
162 #define VIA_CRDR_SDSTS_DATA_MASK\
163 (VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_DT \
164 | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)
166 #define VIA_CRDR_SDSTATUS2 0x2a
170 #define VIA_CRDR_SDSTS_CFE 0x80
172 #define VIA_CRDR_SDRSPTMO 0x2C
174 #define VIA_CRDR_SDCLKSEL 0x30
176 #define VIA_CRDR_SDEXTCTRL 0x34
177 #define VIS_CRDR_SDEXTCTRL_AUTOSTOP_SD 0x01
178 #define VIS_CRDR_SDEXTCTRL_SHIFT_9 0x02
179 #define VIS_CRDR_SDEXTCTRL_MMC_8BIT 0x04
180 #define VIS_CRDR_SDEXTCTRL_RELD_BLK 0x08
181 #define VIS_CRDR_SDEXTCTRL_BAD_CMDA 0x10
182 #define VIS_CRDR_SDEXTCTRL_BAD_DATA 0x20
183 #define VIS_CRDR_SDEXTCTRL_AUTOSTOP_SPI 0x40
184 #define VIA_CRDR_SDEXTCTRL_HISPD 0x80
191 #define VIA_CRDR_DMABASEADD 0x0
192 #define VIA_CRDR_DMACOUNTER 0x4
194 #define VIA_CRDR_DMACTRL 0x8
200 #define VIA_CRDR_DMACTRL_DIR 0x100
201 #define VIA_CRDR_DMACTRL_ENIRQ 0x10000
202 #define VIA_CRDR_DMACTRL_SFTRST 0x1000000
204 #define VIA_CRDR_DMASTS 0xc
206 #define VIA_CRDR_DMASTART 0x10
214 #define VIA_CRDR_PCICLKGATT 0x2
220 #define VIA_CRDR_PCICLKGATT_SFTRST 0x01
228 #define VIA_CRDR_PCICLKGATT_3V3 0x10
236 #define VIA_CRDR_PCICLKGATT_PAD_PWRON 0x20
238 #define VIA_CRDR_PCISDCCLK 0x5
240 #define VIA_CRDR_PCIDMACLK 0x7
241 #define VIA_CRDR_PCIDMACLK_SDC 0x2
243 #define VIA_CRDR_PCIINTCTRL 0x8
244 #define VIA_CRDR_PCIINTCTRL_SDCIRQEN 0x04
246 #define VIA_CRDR_PCIINTSTATUS 0x9
247 #define VIA_CRDR_PCIINTSTATUS_SDC 0x04
249 #define VIA_CRDR_PCITMOCTRL 0xa
250 #define VIA_CRDR_PCITMOCTRL_NO 0x0
251 #define VIA_CRDR_PCITMOCTRL_32US 0x1
252 #define VIA_CRDR_PCITMOCTRL_256US 0x2
253 #define VIA_CRDR_PCITMOCTRL_1024US 0x3
254 #define VIA_CRDR_PCITMOCTRL_256MS 0x4
255 #define VIA_CRDR_PCITMOCTRL_512MS 0x5
256 #define VIA_CRDR_PCITMOCTRL_1024MS 0x6
323 #define VIA_CRDR_QUIRK_300MS_PWRDELAY 0x0001
338 pr_debug(
"SDCONTROL=%08x, SDCMDARG=%08x, SDBUSMODE=%08x\n",
342 pr_debug(
"SDBLKLEN=%08x, SDCURBLKCNT=%08x, SDINTMASK=%08x\n",
346 pr_debug(
"SDSTATUS=%08x, SDCLKSEL=%08x, SDEXTCTRL=%08x\n",
356 pr_debug(
"PCI Control Registers:\n");
357 pr_debug(
"PCICLKGATT=%02x, PCISDCCLK=%02x, PCIDMACLK=%02x\n",
361 pr_debug(
"PCIINTCTRL=%02x, PCIINTSTATUS=%02x\n",
473 dev_info(host->
mmc->parent,
"forcing card speed to 8MHz\n");
503 blk_reg = data->
blksz - 1;
505 blk_reg |= (data->
blocks) << 16;
520 cmd->
resp[0] = ((
u8) (dwdata1)) |
521 (((
u8) (dwdata0 >> 24)) << 8) |
522 (((
u8) (dwdata0 >> 16)) << 16) |
523 (((
u8) (dwdata0 >> 8)) << 24);
525 cmd->
resp[1] = ((
u8) (dwdata2)) |
526 (((
u8) (dwdata1 >> 24)) << 8) |
527 (((
u8) (dwdata1 >> 16)) << 16) |
528 (((
u8) (dwdata1 >> 8)) << 24);
530 cmd->
resp[2] = ((
u8) (dwdata3)) |
531 (((
u8) (dwdata2 >> 24)) << 8) |
532 (((
u8) (dwdata2 >> 16)) << 16) |
533 (((
u8) (dwdata2 >> 8)) << 24);
535 cmd->
resp[3] = 0xff |
536 ((((
u8) (dwdata3 >> 24))) << 8) |
537 (((
u8) (dwdata3 >> 16)) << 16) |
538 (((
u8) (dwdata3 >> 8)) << 24);
541 cmd->
resp[0] = ((dwdata0 & 0xff) << 24) |
542 (((dwdata0 >> 8) & 0xff) << 16) |
543 (((dwdata0 >> 16) & 0xff) << 8) | (dwdata1 & 0xff);
546 cmd->
resp[1] = ((dwdata1 & 0xff) << 24) |
547 (((dwdata1 >> 8) & 0xff) << 16) |
548 (((dwdata1 >> 16) & 0xff) << 8);
566 cmdctrl = cmd->
opcode << 8;
593 via_sdc_preparedata(host, data);
613 if (cmd == host->
mrq->stop)
642 via_sdc_send_command(host, data->
stop);
649 via_sdc_get_response(host, host->
cmd);
651 host->
cmd->error = 0;
653 if (!host->
cmd->data)
666 host = mmc_priv(mmc);
685 via_sdc_send_command(host, mrq->
cmd);
689 spin_unlock_irqrestore(&host->
lock, flags);
693 unsigned short power,
unsigned int on)
714 spin_unlock_irqrestore(&host->
lock, flags);
716 via_pwron_sleep(host);
724 u32 org_data, sdextctrl;
727 host = mmc_priv(mmc);
753 if (ios->
clock >= 48000000)
755 else if (ios->
clock >= 33000000)
757 else if (ios->
clock >= 24000000)
759 else if (ios->
clock >= 16000000)
761 else if (ios->
clock >= 12000000)
763 else if (ios->
clock >= 8000000)
773 spin_unlock_irqrestore(&host->
lock, flags);
776 via_sdc_set_power(host, ios->
vdd, 1);
778 via_sdc_set_power(host, ios->
vdd, 0);
781 static int via_sdc_get_ro(
struct mmc_host *mmc)
787 host = mmc_priv(mmc);
793 spin_unlock_irqrestore(&host->
lock, flags);
799 .request = via_sdc_request,
800 .set_ios = via_sdc_set_ios,
801 .get_ro = via_sdc_get_ro,
811 via_save_pcictrlreg(host);
812 via_save_sdcreg(host);
814 spin_unlock_irqrestore(&host->
lock, flags);
822 via_pwron_sleep(host);
829 via_restore_pcictrlreg(host);
830 via_restore_sdcreg(host);
833 spin_unlock_irqrestore(&host->
lock, flags);
841 pr_err(
"%s: Got command interrupt 0x%x even "
842 "though no command operation was in progress.\n",
852 if (host->
cmd->error)
855 via_sdc_finish_command(host);
867 via_sdc_finish_data(host);
881 spin_lock(&sdhost->
lock);
900 writew(sd_status & VIA_CRDR_SDSTS_CIR,
906 sd_status &= ~VIA_CRDR_SDSTS_CIR;
908 writew(sd_status & VIA_CRDR_SDSTS_CMD_MASK,
910 via_sdc_cmd_isr(sdhost, sd_status & VIA_CRDR_SDSTS_CMD_MASK);
913 writew(sd_status & VIA_CRDR_SDSTS_DATA_MASK,
915 via_sdc_data_isr(sdhost, sd_status & VIA_CRDR_SDSTS_DATA_MASK);
920 pr_err(
"%s: Unexpected interrupt 0x%x\n",
929 spin_unlock(&sdhost->
lock);
934 static void via_sdc_timeout(
unsigned long ulongdata)
944 pr_err(
"%s: Timeout waiting for hardware interrupt."
946 sdhost->
mrq->cmd->opcode);
952 via_sdc_finish_data(sdhost);
963 spin_unlock_irqrestore(&sdhost->
lock, flags);
966 static void via_sdc_tasklet_finish(
unsigned long param)
982 spin_unlock_irqrestore(&host->
lock, flags);
1008 pr_err(
"%s: Card removed during transfer!\n",
1015 spin_unlock_irqrestore(&host->
lock, flags);
1017 via_reset_pcictrl(host);
1023 spin_unlock_irqrestore(&host->
lock, flags);
1025 via_print_pcictrl(host);
1026 via_print_sdchc(host);
1040 host->
timer.function = via_sdc_timeout;
1048 mmc->
ops = &via_sdc_ops;
1062 (
unsigned long)host);
1095 ": VIA SDMMC controller found at %s [%04x:%04x] (rev %x)\n",
1096 pci_name(pcidev), (
int)pcidev->
vendor, (
int)pcidev->
device,
1116 sdhost = mmc_priv(mmc);
1139 via_pwron_sleep(sdhost);
1144 via_init_mmc_host(sdhost);
1182 unsigned long flags;
1195 pr_err(
"%s: Controller removed during "
1203 if (sdhost->
mrq->stop)
1207 spin_unlock_irqrestore(&sdhost->
lock, flags);
1229 ": VIA SDMMC controller at %s [%04x:%04x] has been removed\n",
1230 pci_name(pcidev), (
int)pcidev->
vendor, (
int)pcidev->
device);
1265 via_print_pcictrl(host);
1266 via_print_sdchc(host);
1274 host = pci_get_drvdata(pcidev);
1276 via_save_pcictrlreg(host);
1277 via_save_sdcreg(host);
1295 sdhost = pci_get_drvdata(pcidev);
1303 via_pwron_sleep(sdhost);
1316 via_restore_pcictrlreg(sdhost);
1317 via_init_sdc_pm(sdhost);
1326 #define via_sd_suspend NULL
1327 #define via_sd_resume NULL
1333 .id_table = via_ids,
1334 .probe = via_sd_probe,