All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stafford Horne <shorne@gmail.com>
To: Gabriel Somlo <gsomlo@gmail.com>
Cc: linux-kernel@vger.kernel.org, robh+dt@kernel.org,
	devicetree@vger.kernel.org, ulf.hansson@linaro.org,
	linux-mmc@vger.kernel.org, kgugala@antmicro.com,
	mholenko@antmicro.com, krakoczy@antmicro.com,
	mdudek@internships.antmicro.com, paulus@ozlabs.org,
	joel@jms.id.au, geert@linux-m68k.org,
	david.abdurachmanov@sifive.com, florent@enjoy-digital.fr
Subject: Re: [PATCH v1 3/3] mmc: Add driver for LiteX's LiteSDCard interface
Date: Sat, 4 Dec 2021 16:29:34 +0900	[thread overview]
Message-ID: <YasY3npZ6vlhbtFz@antec> (raw)
In-Reply-To: <20211203234155.2319803-4-gsomlo@gmail.com>

On Fri, Dec 03, 2021 at 06:41:55PM -0500, Gabriel Somlo wrote:
> LiteX (https://github.com/enjoy-digital/litex) is a SoC framework
> that targets FPGAs. LiteSDCard is a small footprint, configurable
> SDCard core commonly used in LiteX designs.
> 
> The driver was first written in May 2020 and has been maintained
> cooperatively by the LiteX community. Thanks to all contributors!
> 
> Co-developed-by: Kamil Rakoczy <krakoczy@antmicro.com>
> Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
> Co-developed-by: Maciej Dudek <mdudek@internships.antmicro.com>
> Signed-off-by: Maciej Dudek <mdudek@internships.antmicro.com>
> Co-developed-by: Paul Mackerras <paulus@ozlabs.org>
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
> Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
> Cc: Mateusz Holenko <mholenko@antmicro.com>
> Cc: Karol Gugala <kgugala@antmicro.com>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Stafford Horne <shorne@gmail.com>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: David Abdurachmanov <david.abdurachmanov@sifive.com>
> Cc: Florent Kermarrec <florent@enjoy-digital.fr>
> ---
>  drivers/mmc/host/Kconfig     |   6 +
>  drivers/mmc/host/Makefile    |   1 +
>  drivers/mmc/host/litex_mmc.c | 677 +++++++++++++++++++++++++++++++++++
>  3 files changed, 684 insertions(+)
>  create mode 100644 drivers/mmc/host/litex_mmc.c
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 5af8494c31b5..84c64e72195d 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -1093,3 +1093,9 @@ config MMC_OWL
>  
>  config MMC_SDHCI_EXTERNAL_DMA
>  	bool
> +
> +config MMC_LITEX
> +	tristate "Support for the MMC Controller in LiteX SOCs"
> +	depends on OF && LITEX

Shall we allow compile test here like this?

       depends on OF || COMPILE_TEST
       depends on LITEX || COMPILE_TEST

This is what was added for liteuart [0].

[0] https://lore.kernel.org/all/CAHp75Ve9MB4MW9KDPoNhnPa8TCabmMgLbt6H7qrGgwmA8CpdNg@mail.gmail.com/T/#mad93ad951031f8e975a1c632873f516598aec272

> +	help
> +	  Generic MCC driver for LiteX
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index ea36d379bd3c..4e4ceb32c4b4 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_MMC_CQHCI)			+= cqhci.o
>  cqhci-y					+= cqhci-core.o
>  cqhci-$(CONFIG_MMC_CRYPTO)		+= cqhci-crypto.o
>  obj-$(CONFIG_MMC_HSQ)			+= mmc_hsq.o
> +obj-$(CONFIG_MMC_LITEX)			+= litex_mmc.o
>  
>  ifeq ($(CONFIG_CB710_DEBUG),y)
>  	CFLAGS-cb710-mmc	+= -DDEBUG
> diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
> new file mode 100644
> index 000000000000..3877379757cd
> --- /dev/null
> +++ b/drivers/mmc/host/litex_mmc.c
> @@ -0,0 +1,677 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * LiteX LiteSDCard driver
> + *
> + * Copyright (C) 2019-2020 Antmicro <www.antmicro.com>
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/litex.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/mmc/sd.h>
> +#include <linux/mmc/mmc.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/slot-gpio.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +
> +#define LITEX_PHY_CARDDETECT  0x00
> +#define LITEX_PHY_CLOCKERDIV  0x04
> +#define LITEX_PHY_INITIALIZE  0x08
> +#define LITEX_PHY_WRITESTATUS 0x0C
> +#define LITEX_CORE_CMDARG     0x00
> +#define LITEX_CORE_CMDCMD     0x04
> +#define LITEX_CORE_CMDSND     0x08
> +#define LITEX_CORE_CMDRSP     0x0C
> +#define LITEX_CORE_CMDEVT     0x1C
> +#define LITEX_CORE_DATAEVT    0x20
> +#define LITEX_CORE_BLKLEN     0x24
> +#define LITEX_CORE_BLKCNT     0x28
> +#define LITEX_BLK2MEM_BASE    0x00
> +#define LITEX_BLK2MEM_LEN     0x08
> +#define LITEX_BLK2MEM_ENA     0x0C
> +#define LITEX_BLK2MEM_DONE    0x10
> +#define LITEX_BLK2MEM_LOOP    0x14
> +#define LITEX_MEM2BLK_BASE    0x00
> +#define LITEX_MEM2BLK_LEN     0x08
> +#define LITEX_MEM2BLK_ENA     0x0C
> +#define LITEX_MEM2BLK_DONE    0x10
> +#define LITEX_MEM2BLK_LOOP    0x14
> +#define LITEX_MEM2BLK         0x18
> +#define LITEX_IRQ_STATUS      0x00
> +#define LITEX_IRQ_PENDING     0x04
> +#define LITEX_IRQ_ENABLE      0x08
> +
> +#define SDCARD_CTRL_DATA_TRANSFER_NONE  0
> +#define SDCARD_CTRL_DATA_TRANSFER_READ  1
> +#define SDCARD_CTRL_DATA_TRANSFER_WRITE 2
> +
> +#define SDCARD_CTRL_RESPONSE_NONE       0
> +#define SDCARD_CTRL_RESPONSE_SHORT      1
> +#define SDCARD_CTRL_RESPONSE_LONG       2
> +#define SDCARD_CTRL_RESPONSE_SHORT_BUSY 3
> +
> +#define SD_OK         0
> +#define SD_WRITEERROR 1
> +#define SD_TIMEOUT    2
> +#define SD_CRCERROR   3
> +#define SD_ERR_OTHER  4
> +
> +#define SDIRQ_CARD_DETECT    1
> +#define SDIRQ_SD_TO_MEM_DONE 2
> +#define SDIRQ_MEM_TO_SD_DONE 4
> +#define SDIRQ_CMD_DONE       8
> +
> +struct litex_mmc_host {
> +	struct mmc_host *mmc;
> +	struct platform_device *dev;
> +
> +	void __iomem *sdphy;
> +	void __iomem *sdcore;
> +	void __iomem *sdreader;
> +	void __iomem *sdwriter;
> +	void __iomem *sdirq;
> +
> +	u32 resp[4];
> +	u16 rca;
> +
> +	void *buffer;
> +	size_t buf_size;
> +	dma_addr_t dma;
> +
> +	unsigned int freq;
> +	unsigned int clock;
> +	bool is_bus_width_set;
> +	bool app_cmd;
> +
> +	int irq;
> +	struct completion cmd_done;
> +};
> +
> +static int
> +sdcard_wait_done(void __iomem *reg)
> +{
> +	u8 evt;
> +
> +	for (;;) {
> +		evt = litex_read8(reg);
> +		if (evt & 0x1)
> +			break;
> +		udelay(5);
> +	}
Should we replace this with something like read_poll_timeout?

	if (read_poll_timeout(litex_read8, evt, (evt & 0x1),
			      5, 20000, false, reg)) {
       		pr_err ("read timeout ....");
		return SD_TIMEOUT;
	}

Otherwise we could be locked here forever.

> +	if (evt == 0x1)
> +		return SD_OK;
> +	if (evt & 0x2)
> +		return SD_WRITEERROR;
> +	if (evt & 0x4)
> +		return SD_TIMEOUT;
> +	if (evt & 0x8)
> +		return SD_CRCERROR;
> +	pr_err("%s: unknown error evt=%x\n", __func__, evt);
> +	return SD_ERR_OTHER;
> +}
> +
> +static int
> +send_cmd(struct litex_mmc_host *host,
> +	 u8 cmd, u32 arg, u8 response_len, u8 transfer)
> +{
> +	void __iomem *reg;
> +	ulong n;
> +	u8 i;
> +	int status;
> +
> +	litex_write32(host->sdcore + LITEX_CORE_CMDARG, arg);
> +	litex_write32(host->sdcore + LITEX_CORE_CMDCMD,
> +		      cmd << 8 | transfer << 5 | response_len);
> +	litex_write8(host->sdcore + LITEX_CORE_CMDSND, 1);
> +
> +	/* Wait for an interrupt if we have an interrupt and either there is
> +	 * data to be transferred, or if the card can report busy via DAT0.
> +	 */
> +	if (host->irq > 0 &&
> +	    (transfer != SDCARD_CTRL_DATA_TRANSFER_NONE ||
> +	     response_len == SDCARD_CTRL_RESPONSE_SHORT_BUSY)) {
> +		reinit_completion(&host->cmd_done);
> +		litex_write32(host->sdirq + LITEX_IRQ_ENABLE,
> +			      SDIRQ_CMD_DONE | SDIRQ_CARD_DETECT);
> +		wait_for_completion(&host->cmd_done);
> +	}
> +
> +	status = sdcard_wait_done(host->sdcore + LITEX_CORE_CMDEVT);
> +
> +	if (status != SD_OK) {
> +		pr_err("Command (cmd %d) failed, status %d\n", cmd, status);
> +		return status;
> +	}
> +
> +	if (response_len != SDCARD_CTRL_RESPONSE_NONE) {
> +		reg = host->sdcore + LITEX_CORE_CMDRSP;
> +		for (i = 0; i < 4; i++) {
> +			host->resp[i] = litex_read32(reg);
> +			reg += sizeof(u32);
> +		}
> +	}
> +
> +	if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR)
> +		host->rca = (host->resp[3] >> 16) & 0xffff;
> +
> +	host->app_cmd = (cmd == MMC_APP_CMD);
> +
> +	if (transfer == SDCARD_CTRL_DATA_TRANSFER_NONE)
> +		return status; /* SD_OK from prior sdcard_wait_done(cmd_evt) */
> +
> +	status = sdcard_wait_done(host->sdcore + LITEX_CORE_DATAEVT);
> +	if (status != SD_OK) {
> +		pr_err("Data xfer (cmd %d) failed, status %d\n", cmd, status);
> +		return status;
> +	}
> +
> +	/* wait for completion of (read or write) DMA transfer */
> +	reg = (transfer == SDCARD_CTRL_DATA_TRANSFER_READ) ?
> +		host->sdreader + LITEX_BLK2MEM_DONE :
> +		host->sdwriter + LITEX_MEM2BLK_DONE;
> +	n = jiffies + (HZ << 1);
> +	while ((litex_read8(reg) & 0x01) == 0)
> +		if (time_after(jiffies, n)) {
> +			pr_err("DMA timeout (cmd %d)\n", cmd);
> +			return SD_TIMEOUT;
> +		}

We could use read_poll_timeout here too.

> +
> +	return status;
> +}
> +

-Stafford

  parent reply	other threads:[~2021-12-04  7:29 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-03 23:41 [PATCH v1 0/3] mmc: Add LiteSDCard mmc driver Gabriel Somlo
2021-12-03 23:41 ` [PATCH v1 1/3] MAINTAINERS: co-maintain LiteX platform Gabriel Somlo
2021-12-03 23:41 ` [PATCH v1 2/3] dt-bindings: mmc: Add bindings for LiteSDCard Gabriel Somlo
2021-12-06  9:38   ` Geert Uytterhoeven
2021-12-06 12:35     ` Gabriel L. Somlo
2021-12-03 23:41 ` [PATCH v1 3/3] mmc: Add driver for LiteX's LiteSDCard interface Gabriel Somlo
2021-12-04  0:20   ` Randy Dunlap
2021-12-04  0:33     ` Gabriel L. Somlo
2021-12-04  4:41   ` kernel test robot
2021-12-04  4:41     ` kernel test robot
2021-12-04  7:29   ` Stafford Horne [this message]
2021-12-05 21:39   ` Stafford Horne
2021-12-05 22:55     ` Gabriel L. Somlo
2021-12-06 10:53   ` Joel Stanley
2021-12-06 12:16     ` Geert Uytterhoeven
2021-12-06 23:51       ` Joel Stanley
2021-12-07  0:53         ` Gabriel L. Somlo
2021-12-07  8:01         ` Geert Uytterhoeven
2021-12-07  1:23     ` Gabriel L. Somlo
2021-12-07  2:46       ` Joel Stanley
2021-12-07 18:51         ` Gabriel L. Somlo
2021-12-08 16:46     ` Gabriel L. Somlo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YasY3npZ6vlhbtFz@antec \
    --to=shorne@gmail.com \
    --cc=david.abdurachmanov@sifive.com \
    --cc=devicetree@vger.kernel.org \
    --cc=florent@enjoy-digital.fr \
    --cc=geert@linux-m68k.org \
    --cc=gsomlo@gmail.com \
    --cc=joel@jms.id.au \
    --cc=kgugala@antmicro.com \
    --cc=krakoczy@antmicro.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=mdudek@internships.antmicro.com \
    --cc=mholenko@antmicro.com \
    --cc=paulus@ozlabs.org \
    --cc=robh+dt@kernel.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.