Lines Matching +full:sdhci +full:- +full:caps +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0-or-later
9 * sdhci.c, copyright (C) 2005-2006 Pierre Ossman
38 pci_write_config_byte(host->pdev, SD_PCICFG_CLKSTOP, in toshsd_init()
40 pci_write_config_byte(host->pdev, SD_PCICFG_CARDDETECT, 2); in toshsd_init()
43 iowrite16(0, host->ioaddr + SD_SOFTWARERESET); /* assert */ in toshsd_init()
45 iowrite16(1, host->ioaddr + SD_SOFTWARERESET); /* deassert */ in toshsd_init()
49 iowrite16(0, host->ioaddr + SD_CARDCLOCKCTRL); in toshsd_init()
50 iowrite32(0, host->ioaddr + SD_CARDSTATUS); in toshsd_init()
51 iowrite32(0, host->ioaddr + SD_ERRORSTATUS0); in toshsd_init()
52 iowrite16(0, host->ioaddr + SD_STOPINTERNAL); in toshsd_init()
55 iowrite16(0x100, host->ioaddr + SDIO_BASE + SDIO_CLOCKNWAITCTRL); in toshsd_init()
58 pci_write_config_byte(host->pdev, SD_PCICFG_SDLED_ENABLE1, in toshsd_init()
60 pci_write_config_byte(host->pdev, SD_PCICFG_SDLED_ENABLE2, in toshsd_init()
68 host->ioaddr + SD_INTMASKCARD); in toshsd_init()
70 iowrite16(0x1000, host->ioaddr + SD_TRANSACTIONCTRL); in toshsd_init()
82 if (ios->clock) { in __toshsd_set_ios()
86 while (ios->clock < HCLK / div) in __toshsd_set_ios()
92 pci_write_config_byte(host->pdev, SD_PCICFG_CLKMODE, in __toshsd_set_ios()
96 pci_write_config_byte(host->pdev, SD_PCICFG_CLKMODE, 0); in __toshsd_set_ios()
99 iowrite16(clk, host->ioaddr + SD_CARDCLOCKCTRL); in __toshsd_set_ios()
103 iowrite16(0, host->ioaddr + SD_CARDCLOCKCTRL); in __toshsd_set_ios()
105 switch (ios->power_mode) { in __toshsd_set_ios()
107 pci_write_config_byte(host->pdev, SD_PCICFG_POWER1, in __toshsd_set_ios()
114 pci_write_config_byte(host->pdev, SD_PCICFG_POWER1, in __toshsd_set_ios()
116 pci_write_config_byte(host->pdev, SD_PCICFG_POWER2, in __toshsd_set_ios()
122 switch (ios->bus_width) { in __toshsd_set_ios()
127 host->ioaddr + SD_CARDOPTIONSETUP); in __toshsd_set_ios()
133 host->ioaddr + SD_CARDOPTIONSETUP); in __toshsd_set_ios()
140 iowrite16(state, host->ioaddr + SDIO_BASE + SDIO_LEDCTRL); in toshsd_set_led()
145 struct mmc_request *mrq = host->mrq; in toshsd_finish_request()
148 host->mrq = NULL; in toshsd_finish_request()
149 host->cmd = NULL; in toshsd_finish_request()
150 host->data = NULL; in toshsd_finish_request()
153 mmc_request_done(host->mmc, mrq); in toshsd_finish_request()
159 struct mmc_data *data = host->data; in toshsd_thread_irq()
160 struct sg_mapping_iter *sg_miter = &host->sg_miter; in toshsd_thread_irq()
166 dev_warn(&host->pdev->dev, "Spurious Data IRQ\n"); in toshsd_thread_irq()
167 if (host->cmd) { in toshsd_thread_irq()
168 host->cmd->error = -EIO; in toshsd_thread_irq()
173 spin_lock_irqsave(&host->lock, flags); in toshsd_thread_irq()
178 buf = sg_miter->addr; in toshsd_thread_irq()
183 count = sg_miter->length; in toshsd_thread_irq()
184 if (count > data->blksz) in toshsd_thread_irq()
185 count = data->blksz; in toshsd_thread_irq()
187 dev_dbg(&host->pdev->dev, "count: %08x, flags %08x\n", count, in toshsd_thread_irq()
188 data->flags); in toshsd_thread_irq()
191 if (data->flags & MMC_DATA_READ) in toshsd_thread_irq()
192 ioread32_rep(host->ioaddr + SD_DATAPORT, buf, count >> 2); in toshsd_thread_irq()
194 iowrite32_rep(host->ioaddr + SD_DATAPORT, buf, count >> 2); in toshsd_thread_irq()
196 sg_miter->consumed = count; in toshsd_thread_irq()
200 spin_unlock_irqrestore(&host->lock, flags); in toshsd_thread_irq()
207 struct mmc_command *cmd = host->cmd; in toshsd_cmd_irq()
211 if (!host->cmd) { in toshsd_cmd_irq()
212 dev_warn(&host->pdev->dev, "Spurious CMD irq\n"); in toshsd_cmd_irq()
215 buf = (u8 *)cmd->resp; in toshsd_cmd_irq()
216 host->cmd = NULL; in toshsd_cmd_irq()
218 if (cmd->flags & MMC_RSP_PRESENT && cmd->flags & MMC_RSP_136) { in toshsd_cmd_irq()
221 data = ioread16(host->ioaddr + SD_RESPONSE0); in toshsd_cmd_irq()
224 data = ioread16(host->ioaddr + SD_RESPONSE1); in toshsd_cmd_irq()
227 data = ioread16(host->ioaddr + SD_RESPONSE2); in toshsd_cmd_irq()
230 data = ioread16(host->ioaddr + SD_RESPONSE3); in toshsd_cmd_irq()
233 data = ioread16(host->ioaddr + SD_RESPONSE4); in toshsd_cmd_irq()
236 data = ioread16(host->ioaddr + SD_RESPONSE5); in toshsd_cmd_irq()
239 data = ioread16(host->ioaddr + SD_RESPONSE6); in toshsd_cmd_irq()
242 data = ioread16(host->ioaddr + SD_RESPONSE7); in toshsd_cmd_irq()
244 } else if (cmd->flags & MMC_RSP_PRESENT) { in toshsd_cmd_irq()
246 data = ioread16(host->ioaddr + SD_RESPONSE0); in toshsd_cmd_irq()
249 data = ioread16(host->ioaddr + SD_RESPONSE1); in toshsd_cmd_irq()
254 dev_dbg(&host->pdev->dev, "Command IRQ complete %d %d %x\n", in toshsd_cmd_irq()
255 cmd->opcode, cmd->error, cmd->flags); in toshsd_cmd_irq()
259 if (host->data) in toshsd_cmd_irq()
267 struct mmc_data *data = host->data; in toshsd_data_end_irq()
269 host->data = NULL; in toshsd_data_end_irq()
272 dev_warn(&host->pdev->dev, "Spurious data end IRQ\n"); in toshsd_data_end_irq()
276 if (data->error == 0) in toshsd_data_end_irq()
277 data->bytes_xfered = data->blocks * data->blksz; in toshsd_data_end_irq()
279 data->bytes_xfered = 0; in toshsd_data_end_irq()
281 dev_dbg(&host->pdev->dev, "Completed data request xfr=%d\n", in toshsd_data_end_irq()
282 data->bytes_xfered); in toshsd_data_end_irq()
284 iowrite16(0, host->ioaddr + SD_STOPINTERNAL); in toshsd_data_end_irq()
295 spin_lock(&host->lock); in toshsd_irq()
296 int_status = ioread32(host->ioaddr + SD_CARDSTATUS); in toshsd_irq()
297 int_mask = ioread32(host->ioaddr + SD_INTMASKCARD); in toshsd_irq()
300 dev_dbg(&host->pdev->dev, "IRQ status:%x mask:%x\n", in toshsd_irq()
310 error = -ETIMEDOUT; in toshsd_irq()
311 dev_dbg(&host->pdev->dev, "Timeout\n"); in toshsd_irq()
313 error = -EILSEQ; in toshsd_irq()
314 dev_err(&host->pdev->dev, "BadCRC\n"); in toshsd_irq()
321 dev_err(&host->pdev->dev, "Buffer status error: { %s%s%s%s%s%s}\n", in toshsd_irq()
329 detail = ioread32(host->ioaddr + SD_ERRORSTATUS0); in toshsd_irq()
330 dev_err(&host->pdev->dev, "detail error status { %s%s%s%s%s%s%s%s%s%s%s%s%s}\n", in toshsd_irq()
344 error = -EIO; in toshsd_irq()
348 if (host->cmd) in toshsd_irq()
349 host->cmd->error = error; in toshsd_irq()
351 if (error == -ETIMEDOUT) { in toshsd_irq()
354 host->ioaddr + SD_CARDSTATUS); in toshsd_irq()
357 __toshsd_set_ios(host->mmc, &host->mmc->ios); in toshsd_irq()
366 host->ioaddr + SD_CARDSTATUS); in toshsd_irq()
371 mmc_detect_change(host->mmc, 1); in toshsd_irq()
378 host->ioaddr + SD_CARDSTATUS); in toshsd_irq()
387 host->ioaddr + SD_CARDSTATUS); in toshsd_irq()
394 host->ioaddr + SD_CARDSTATUS); in toshsd_irq()
398 spin_unlock(&host->lock); in toshsd_irq()
404 struct mmc_data *data = host->data; in toshsd_start_cmd()
405 int c = cmd->opcode; in toshsd_start_cmd()
407 dev_dbg(&host->pdev->dev, "Command opcode: %d\n", cmd->opcode); in toshsd_start_cmd()
409 if (cmd->opcode == MMC_STOP_TRANSMISSION) { in toshsd_start_cmd()
411 host->ioaddr + SD_STOPINTERNAL); in toshsd_start_cmd()
413 cmd->resp[0] = cmd->opcode; in toshsd_start_cmd()
414 cmd->resp[1] = 0; in toshsd_start_cmd()
415 cmd->resp[2] = 0; in toshsd_start_cmd()
416 cmd->resp[3] = 0; in toshsd_start_cmd()
441 dev_err(&host->pdev->dev, "Unknown response type %d\n", in toshsd_start_cmd()
446 host->cmd = cmd; in toshsd_start_cmd()
448 if (cmd->opcode == MMC_APP_CMD) in toshsd_start_cmd()
451 if (cmd->opcode == MMC_GO_IDLE_STATE) in toshsd_start_cmd()
452 c |= (3 << 8); /* removed from ipaq-asic3.h for some reason */ in toshsd_start_cmd()
457 if (data->blocks > 1) { in toshsd_start_cmd()
459 host->ioaddr + SD_STOPINTERNAL); in toshsd_start_cmd()
463 if (data->flags & MMC_DATA_READ) in toshsd_start_cmd()
470 iowrite32(cmd->arg, host->ioaddr + SD_ARG0); in toshsd_start_cmd()
471 iowrite16(c, host->ioaddr + SD_CMD); in toshsd_start_cmd()
478 dev_dbg(&host->pdev->dev, "setup data transfer: blocksize %08x nr_blocks %d, offset: %08x\n", in toshsd_start_data()
479 data->blksz, data->blocks, data->sg->offset); in toshsd_start_data()
481 host->data = data; in toshsd_start_data()
483 if (data->flags & MMC_DATA_READ) in toshsd_start_data()
488 sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); in toshsd_start_data()
491 iowrite16(data->blocks, host->ioaddr + SD_BLOCKCOUNT); in toshsd_start_data()
492 iowrite16(data->blksz, host->ioaddr + SD_CARDXFERDATALEN); in toshsd_start_data()
502 if (!(ioread16(host->ioaddr + SD_CARDSTATUS) & SD_CARD_PRESENT_0)) { in toshsd_request()
503 mrq->cmd->error = -ENOMEDIUM; in toshsd_request()
508 spin_lock_irqsave(&host->lock, flags); in toshsd_request()
510 WARN_ON(host->mrq != NULL); in toshsd_request()
512 host->mrq = mrq; in toshsd_request()
514 if (mrq->data) in toshsd_request()
515 toshsd_start_data(host, mrq->data); in toshsd_request()
519 toshsd_start_cmd(host, mrq->cmd); in toshsd_request()
521 spin_unlock_irqrestore(&host->lock, flags); in toshsd_request()
529 spin_lock_irqsave(&host->lock, flags); in toshsd_set_ios()
531 spin_unlock_irqrestore(&host->lock, flags); in toshsd_set_ios()
539 return !(ioread16(host->ioaddr + SD_CARDSTATUS) & SD_CARD_WRITE_PROTECT); in toshsd_get_ro()
546 return !!(ioread16(host->ioaddr + SD_CARDSTATUS) & SD_CARD_PRESENT_0); in toshsd_get_cd()
559 /* mask all interrupts */ in toshsd_powerdown()
560 iowrite32(0xffffffff, host->ioaddr + SD_INTMASKCARD); in toshsd_powerdown()
562 iowrite16(0x000, host->ioaddr + SDIO_BASE + SDIO_CLOCKNWAITCTRL); in toshsd_powerdown()
563 iowrite16(0, host->ioaddr + SD_CARDCLOCKCTRL); in toshsd_powerdown()
565 pci_write_config_byte(host->pdev, SD_PCICFG_POWER1, SD_PCICFG_PWR1_OFF); in toshsd_powerdown()
567 pci_write_config_byte(host->pdev, SD_PCICFG_CLKSTOP, 0); in toshsd_powerdown()
615 mmc = devm_mmc_alloc_host(&pdev->dev, sizeof(*host)); in toshsd_probe()
617 ret = -ENOMEM; in toshsd_probe()
622 host->mmc = mmc; in toshsd_probe()
624 host->pdev = pdev; in toshsd_probe()
631 host->ioaddr = pci_iomap(pdev, 0, 0); in toshsd_probe()
632 if (!host->ioaddr) { in toshsd_probe()
633 ret = -ENOMEM; in toshsd_probe()
638 mmc->ops = &toshsd_ops; in toshsd_probe()
639 mmc->caps = MMC_CAP_4_BIT_DATA; in toshsd_probe()
640 mmc->ocr_avail = MMC_VDD_32_33; in toshsd_probe()
642 mmc->f_min = HCLK / 512; in toshsd_probe()
643 mmc->f_max = HCLK; in toshsd_probe()
645 spin_lock_init(&host->lock); in toshsd_probe()
649 ret = request_threaded_irq(pdev->irq, toshsd_irq, toshsd_thread_irq, in toshsd_probe()
659 dev_dbg(&pdev->dev, "MMIO %pa, IRQ %d\n", &base, pdev->irq); in toshsd_probe()
661 pm_suspend_ignore_children(&pdev->dev, 1); in toshsd_probe()
666 free_irq(pdev->irq, host); in toshsd_probe()
668 pci_iounmap(pdev, host->ioaddr); in toshsd_probe()
682 mmc_remove_host(host->mmc); in toshsd_remove()
684 free_irq(pdev->irq, host); in toshsd_remove()
685 pci_iounmap(pdev, host->ioaddr); in toshsd_remove()