From 61598093bbdd283a7edc367d900f223070ead8d2 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:43:03 +0000
Subject: [PATCH] add ax88772C AX88772C_eeprom_tools
---
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