From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/mmc/host/tmio_mmc_core.c | 303 +++++++++++-------------------------------------- 1 files changed, 71 insertions(+), 232 deletions(-) diff --git a/kernel/drivers/mmc/host/tmio_mmc_core.c b/kernel/drivers/mmc/host/tmio_mmc_core.c index 33c9ca8..abf36ac 100644 --- a/kernel/drivers/mmc/host/tmio_mmc_core.c +++ b/kernel/drivers/mmc/host/tmio_mmc_core.c @@ -1,18 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the MMC / SD / SDIO IP found in: * * TC6393XB, TC6391XB, TC6387XB, T7L66XB, ASIC3, SH-Mobile SoCs * - * Copyright (C) 2015-17 Renesas Electronics Corporation - * Copyright (C) 2016-17 Sang Engineering, Wolfram Sang + * Copyright (C) 2015-19 Renesas Electronics Corporation + * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang * Copyright (C) 2017 Horms Solutions, Simon Horman * Copyright (C) 2011 Guennadi Liakhovetski * Copyright (C) 2007 Ian Molton * Copyright (C) 2004 Ian Molton - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. * * This driver draws mainly on scattered spec sheets, Reverse engineering * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit @@ -29,6 +26,7 @@ #include <linux/delay.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/highmem.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -48,7 +46,6 @@ #include <linux/scatterlist.h> #include <linux/sizes.h> #include <linux/spinlock.h> -#include <linux/swiotlb.h> #include <linux/workqueue.h> #include "tmio_mmc.h" @@ -58,6 +55,12 @@ { if (host->dma_ops) host->dma_ops->start(host, data); +} + +static inline void tmio_mmc_end_dma(struct tmio_mmc_host *host) +{ + if (host->dma_ops && host->dma_ops->end) + host->dma_ops->end(host); } static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) @@ -161,100 +164,23 @@ } } -static void tmio_mmc_clk_start(struct tmio_mmc_host *host) -{ - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - - /* HW engineers overrode docs: no sleep needed on R-Car2+ */ - if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) - usleep_range(10000, 11000); - - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); - usleep_range(10000, 11000); - } -} - -static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) -{ - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); - usleep_range(10000, 11000); - } - - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - - /* HW engineers overrode docs: no sleep needed on R-Car2+ */ - if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) - usleep_range(10000, 11000); -} - -static void tmio_mmc_set_clock(struct tmio_mmc_host *host, - unsigned int new_clock) -{ - u32 clk = 0, clock; - - if (new_clock == 0) { - tmio_mmc_clk_stop(host); - return; - } - /* - * Both HS400 and HS200/SD104 set 200MHz, but some devices need to - * set 400MHz to distinguish the CPG settings in HS400. - */ - if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 && - host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 && - new_clock == 200000000) - new_clock = 400000000; - - if (host->clk_update) - clock = host->clk_update(host, new_clock) / 512; - else - clock = host->mmc->f_min; - - for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) - clock <<= 1; - - /* 1/1 clock is option */ - if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && - ((clk >> 22) & 0x1)) { - if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400)) - clk |= 0xff; - else - clk &= ~0xff; - } - - if (host->set_clk_div) - host->set_clk_div(host->pdev, (clk >> 22) & 1); - - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); - if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) - usleep_range(10000, 11000); - - tmio_mmc_clk_start(host); -} - static void tmio_mmc_reset(struct tmio_mmc_host *host) { /* FIXME - should we set stop clock reg here */ sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) - sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); usleep_range(10000, 11000); sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) - sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); usleep_range(10000, 11000); + + if (host->reset) + host->reset(host); + + tmio_mmc_abort_dma(host); if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) { sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); } - } static void tmio_mmc_reset_work(struct work_struct *work) @@ -299,8 +225,6 @@ /* Ready for new calls */ host->mrq = NULL; - - tmio_mmc_abort_dma(host); mmc_request_done(host->mmc, mrq); } @@ -447,7 +371,7 @@ unsigned int count; unsigned long flags; - if ((host->chan_tx || host->chan_rx) && !host->force_pio) { + if (host->dma_on) { pr_err("PIO IRQ in DMA mode!\n"); return; } else if (!data) { @@ -519,7 +443,7 @@ */ if (data->flags & MMC_DATA_READ) { - if (host->chan_rx && !host->force_pio) + if (host->dma_on) tmio_mmc_check_bounce_buffer(host); dev_dbg(&host->pdev->dev, "Complete Rx request %p\n", host->mrq); @@ -556,7 +480,7 @@ if (stat & TMIO_STAT_CRCFAIL || stat & TMIO_STAT_STOPBIT_ERR || stat & TMIO_STAT_TXUNDERRUN) data->error = -EILSEQ; - if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) { + if (host->dma_on && (data->flags & MMC_DATA_WRITE)) { u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS); bool done = false; @@ -580,7 +504,7 @@ tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND); tmio_mmc_dataend_dma(host); } - } else if (host->chan_rx && (data->flags & MMC_DATA_READ) && !host->force_pio) { + } else if (host->dma_on && (data->flags & MMC_DATA_READ)) { tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND); tmio_mmc_dataend_dma(host); } else { @@ -633,7 +557,7 @@ */ if (host->data && (!cmd->error || cmd->error == -EILSEQ)) { if (host->data->flags & MMC_DATA_READ) { - if (host->force_pio || !host->chan_rx) { + if (!host->dma_on) { tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP); } else { tmio_mmc_disable_mmc_irqs(host, @@ -641,7 +565,7 @@ tasklet_schedule(&host->dma_issue); } } else { - if (host->force_pio || !host->chan_tx) { + if (!host->dma_on) { tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP); } else { tmio_mmc_disable_mmc_irqs(host, @@ -774,7 +698,7 @@ tmio_mmc_init_sg(host, data); host->data = data; - host->force_pio = false; + host->dma_on = false; /* Set transfer length / blocksize */ sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz); @@ -786,59 +710,6 @@ tmio_mmc_start_dma(host, data); return 0; -} - -static void tmio_mmc_hw_reset(struct mmc_host *mmc) -{ - struct tmio_mmc_host *host = mmc_priv(mmc); - - if (host->hw_reset) - host->hw_reset(host); -} - -static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) -{ - struct tmio_mmc_host *host = mmc_priv(mmc); - int i, ret = 0; - - if (!host->init_tuning || !host->select_tuning) - /* Tuning is not supported */ - goto out; - - host->tap_num = host->init_tuning(host); - if (!host->tap_num) - /* Tuning is not supported */ - goto out; - - if (host->tap_num * 2 >= sizeof(host->taps) * BITS_PER_BYTE) { - dev_warn_once(&host->pdev->dev, - "Too many taps, skipping tuning. Please consider updating size of taps field of tmio_mmc_host\n"); - goto out; - } - - bitmap_zero(host->taps, host->tap_num * 2); - - /* Issue CMD19 twice for each tap */ - for (i = 0; i < 2 * host->tap_num; i++) { - if (host->prepare_tuning) - host->prepare_tuning(host, i % host->tap_num); - - ret = mmc_send_tuning(mmc, opcode, NULL); - if (ret == 0) - set_bit(i, host->taps); - - usleep_range(1000, 1200); - } - - ret = host->select_tuning(host); - -out: - if (ret < 0) { - dev_warn(&host->pdev->dev, "Tuning procedure failed\n"); - tmio_mmc_hw_reset(mmc); - } - - return ret; } static void tmio_process_mrq(struct tmio_mmc_host *host, @@ -906,6 +777,8 @@ spin_lock_irqsave(&host->lock, flags); + tmio_mmc_end_dma(host); + mrq = host->mrq; if (IS_ERR_OR_NULL(mrq)) { spin_unlock_irqrestore(&host->lock, flags); @@ -926,8 +799,8 @@ if (mrq->cmd->error || (mrq->data && mrq->data->error)) tmio_mmc_abort_dma(host); - /* SCC error means retune, but executed command was still successful */ - if (host->check_scc_error && host->check_scc_error(host)) + /* Error means retune, but executed command was still successful */ + if (host->check_retune && host->check_retune(host)) mmc_retune_needed(host->mmc); /* If SET_BLOCK_COUNT, continue with main command */ @@ -935,6 +808,9 @@ tmio_process_mrq(host, mrq); return; } + + if (host->fixup_request) + host->fixup_request(host, mrq); mmc_request_done(host->mmc, mrq); } @@ -1051,15 +927,18 @@ switch (ios->power_mode) { case MMC_POWER_OFF: tmio_mmc_power_off(host); - tmio_mmc_clk_stop(host); + /* For R-Car Gen2+, we need to reset SDHI specific SCC */ + if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) + host->reset(host); + host->set_clock(host, 0); break; case MMC_POWER_UP: tmio_mmc_power_on(host, ios->vdd); - tmio_mmc_set_clock(host, ios->clock); + host->set_clock(host, ios->clock); tmio_mmc_set_bus_width(host, ios->bus_width); break; case MMC_POWER_ON: - tmio_mmc_set_clock(host, ios->clock); + host->set_clock(host, ios->clock); tmio_mmc_set_bus_width(host, ios->bus_width); break; } @@ -1105,45 +984,13 @@ return blk_size; } -static int tmio_mmc_prepare_hs400_tuning(struct mmc_host *mmc, - struct mmc_ios *ios) -{ - struct tmio_mmc_host *host = mmc_priv(mmc); - - if (host->prepare_hs400_tuning) - host->prepare_hs400_tuning(host); - - return 0; -} - -static void tmio_mmc_hs400_downgrade(struct mmc_host *mmc) -{ - struct tmio_mmc_host *host = mmc_priv(mmc); - - if (host->hs400_downgrade) - host->hs400_downgrade(host); -} - -static void tmio_mmc_hs400_complete(struct mmc_host *mmc) -{ - struct tmio_mmc_host *host = mmc_priv(mmc); - - if (host->hs400_complete) - host->hs400_complete(host); -} - -static const struct mmc_host_ops tmio_mmc_ops = { +static struct mmc_host_ops tmio_mmc_ops = { .request = tmio_mmc_request, .set_ios = tmio_mmc_set_ios, .get_ro = tmio_mmc_get_ro, .get_cd = tmio_mmc_get_cd, .enable_sdio_irq = tmio_mmc_enable_sdio_irq, .multi_io_quirk = tmio_multi_io_quirk, - .hw_reset = tmio_mmc_hw_reset, - .execute_tuning = tmio_mmc_execute_tuning, - .prepare_hs400_tuning = tmio_mmc_prepare_hs400_tuning, - .hs400_downgrade = tmio_mmc_hs400_downgrade, - .hs400_complete = tmio_mmc_hs400_complete, }; static int tmio_mmc_init_ocr(struct tmio_mmc_host *host) @@ -1158,7 +1005,7 @@ /* use ocr_mask if no regulator */ if (!mmc->ocr_avail) - mmc->ocr_avail = pdata->ocr_mask; + mmc->ocr_avail = pdata->ocr_mask; /* * try again. @@ -1192,12 +1039,10 @@ { struct tmio_mmc_host *host; struct mmc_host *mmc; - struct resource *res; void __iomem *ctl; int ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ctl = devm_ioremap_resource(&pdev->dev, res); + ctl = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ctl)) return ERR_CAST(ctl); @@ -1245,7 +1090,7 @@ int ret; /* - * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from + * Check the sanity of mmc->f_min to prevent host->set_clock() from * looping forever... */ if (mmc->f_min == 0) @@ -1255,37 +1100,28 @@ _host->write16_hook = NULL; _host->set_pwr = pdata->set_pwr; - _host->set_clk_div = pdata->set_clk_div; ret = tmio_mmc_init_ocr(_host); if (ret < 0) return ret; - if (pdata->flags & TMIO_MMC_USE_GPIO_CD) { - ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio, 0); - if (ret) - return ret; - } + /* + * Look for a card detect GPIO, if it fails with anything + * else than a probe deferral, just live without it. + */ + ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0); + if (ret == -EPROBE_DEFER) + return ret; - mmc->caps |= MMC_CAP_ERASE | MMC_CAP_4_BIT_DATA | pdata->capabilities; + mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities; mmc->caps2 |= pdata->capabilities2; mmc->max_segs = pdata->max_segs ? : 32; - mmc->max_blk_size = 512; + mmc->max_blk_size = TMIO_MAX_BLK_SIZE; mmc->max_blk_count = pdata->max_blk_count ? : (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs; - mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; - /* - * Since swiotlb has memory size limitation, this will calculate - * the maximum size locally (because we don't have any APIs for it now) - * and check the current max_req_size. And then, this will update - * the max_req_size if needed as a workaround. - */ - if (swiotlb_max_segment()) { - unsigned int max_size = (1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE; - - if (mmc->max_req_size > max_size) - mmc->max_req_size = max_size; - } + mmc->max_req_size = min_t(size_t, + mmc->max_blk_size * mmc->max_blk_count, + dma_max_mapping_size(&pdev->dev)); mmc->max_seg_size = mmc->max_req_size; if (mmc_can_gpio_ro(mmc)) @@ -1318,11 +1154,13 @@ if (pdata->flags & TMIO_MMC_SDIO_IRQ) _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; - tmio_mmc_clk_stop(_host); + _host->set_clock(_host, 0); tmio_mmc_reset(_host); _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK); - tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL); + if (!_host->sdcard_irq_mask_all) + _host->sdcard_irq_mask_all = TMIO_MASK_ALL; + tmio_mmc_disable_mmc_irqs(_host, _host->sdcard_irq_mask_all); if (_host->native_hotplug) tmio_mmc_enable_mmc_irqs(_host, @@ -1338,6 +1176,7 @@ /* See if we also get DMA */ tmio_mmc_request_dma(_host, pdata); + pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, 50); pm_runtime_use_autosuspend(&pdev->dev); @@ -1348,10 +1187,12 @@ goto remove_host; dev_pm_qos_expose_latency_limit(&pdev->dev, 100); + pm_runtime_put(&pdev->dev); return 0; remove_host: + pm_runtime_put_noidle(&pdev->dev); tmio_mmc_host_remove(_host); return ret; } @@ -1362,11 +1203,10 @@ struct platform_device *pdev = host->pdev; struct mmc_host *mmc = host->mmc; + pm_runtime_get_sync(&pdev->dev); + if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); - - if (!host->native_hotplug) - pm_runtime_get_sync(&pdev->dev); dev_pm_qos_hide_latency_limit(&pdev->dev); @@ -1374,9 +1214,14 @@ cancel_work_sync(&host->done); cancel_delayed_work_sync(&host->delayed_reset_work); tmio_mmc_release_dma(host); + tmio_mmc_disable_mmc_irqs(host, host->sdcard_irq_mask_all); - pm_runtime_put_sync(&pdev->dev); + if (host->native_hotplug) + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } EXPORT_SYMBOL_GPL(tmio_mmc_host_remove); @@ -1399,10 +1244,10 @@ { struct tmio_mmc_host *host = dev_get_drvdata(dev); - tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); + tmio_mmc_disable_mmc_irqs(host, host->sdcard_irq_mask_all); if (host->clk_cache) - tmio_mmc_clk_stop(host); + host->set_clock(host, 0); tmio_mmc_clk_disable(host); @@ -1410,20 +1255,15 @@ } EXPORT_SYMBOL_GPL(tmio_mmc_host_runtime_suspend); -static bool tmio_mmc_can_retune(struct tmio_mmc_host *host) -{ - return host->tap_num && mmc_can_retune(host->mmc); -} - int tmio_mmc_host_runtime_resume(struct device *dev) { struct tmio_mmc_host *host = dev_get_drvdata(dev); - tmio_mmc_reset(host); tmio_mmc_clk_enable(host); + tmio_mmc_reset(host); if (host->clk_cache) - tmio_mmc_set_clock(host, host->clk_cache); + host->set_clock(host, host->clk_cache); if (host->native_hotplug) tmio_mmc_enable_mmc_irqs(host, @@ -1431,8 +1271,7 @@ tmio_mmc_enable_dma(host, true); - if (tmio_mmc_can_retune(host) && host->select_tuning(host)) - dev_warn(&host->pdev->dev, "Tuning selection failed\n"); + mmc_retune_needed(host->mmc); return 0; } -- Gitblit v1.6.2