Skip to contentSkip to conversation

Add support for Amlogic Meson MMC driver

PATCH New Carlo Caione 5 participants 12 messages Feb 27, 2016 – May 11, 2016

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v5 cover Add support for Amlogic Meson MMC driver

From: Carlo Caione <[email protected]>

This patchset adds support for the MMC driver found on the Meson platforms.

Changelog:

v2:
* fix typo in commit message
* avoid the bounce buffer (max_segs == 1)

v3:
* simplify meson_mmc_map_dma() and fix memory leak

v4:
* code and documentation cleanup
* removed redundant variables
* removed useless printing
* introduced MMC_CAP2_NO_SDIO
* removed state machine
* better spinlocks management and positioning

v5:
* split submission in several patches
* update mmc->actual_clock
* fix timeout value
* add clk_prepare_enable()
* add 'meson,sd-port' property

Carlo Caione (4):
mmc: meson: Document Amlogic Meson MMC DT bindings
mmc: meson: Add driver for the SD/MMC host found on Amlogic Meson SoCs
ARM: dts: meson8b: Add MMC nodes
ARM: multi_v7_defconfig: Add Amlogic Meson MMC support

 .../devicetree/bindings/mmc/meson-mmc.txt          |  30 ++
 arch/arm/boot/dts/meson8b-mxq.dts                  |   8 +
 arch/arm/boot/dts/meson8b-odroidc1.dts             |   8 +
 arch/arm/boot/dts/meson8b.dtsi                     |  16 +
 arch/arm/configs/multi_v7_defconfig                |   1 +
 drivers/mmc/host/Kconfig                           |   7 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/meson-mmc.c                       | 535 +++++++++++++++++++++
 8 files changed, 606 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/meson-mmc.txt
 create mode 100644 drivers/mmc/host/meson-mmc.c
Signature · 1 line
1.9.1
#1 lore raw

PATCH v5 1/4 mmc: meson: Document Amlogic Meson MMC DT bindings

From: Carlo Caione <[email protected]>

---
 .../devicetree/bindings/mmc/meson-mmc.txt          | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/meson-mmc.txt
Documentation/devicetree/bindings/mmc/meson-mmc.txt new file +30 -0
new file mode 100644
index 0000000..328157e
@@ -0,0 +1,30 @@
+* Amlogic Meson MMC controller
+
+The highspeed MMC host controller on Amlogic SoCs provides an interface
+for MMC, SD, SDIO and SDHC types of memory cards.
+
+Supported maximum speeds are the ones of the eMMC standard 4.41 as well
+as the speed of SD standard 2.0.
+
+Required properties:
+ - compatible : "amlogic,meson-mmc"
+ - reg : mmc controller base registers
+ - interrupts : mmc controller interrupt
+ - clocks : phandle to clock provider
+ - pinctrl-names : should contain "sdio_a" or "sdio_b"
+ - pinctrl-0: Should specify pin control groups used for this controller
+
+Optional properties:
+ - meson,sd-port : 0 for port A, 1 for port B
+ - for cd, bus-width and additional generic mmc parameters
+   please refer to mmc.txt within this directory
+
+Examples:
+	mmc0: mmc at c1108c20 {
+		pinctrl-names = "sdio_b";
+		pinctrl-0 = <&mmc0_sd_b_pins>;
+		compatible = "amlogic,meson-mmc";
+		reg = <0xc1108c20 0x20>;
+		interrupts = <0 28 1>;
+		clocks = <&clkc CLKID_CLK81>;
+	};
Signature · 1 line
1.9.1
maintainer
#2 lore raw

PATCH v5 1/4 mmc: meson: Document Amlogic Meson MMC DT bindings

Quoted 22 lines · Carlo Caione

From: Carlo Caione <[email protected]>

---
 .../devicetree/bindings/mmc/meson-mmc.txt          | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/meson-mmc.txt
Documentation/devicetree/bindings/mmc/meson-mmc.txt new file +8 -0
new file mode 100644
index 0000000..328157e
@@ -0,0 +1,30 @@
+* Amlogic Meson MMC controller
+
+The highspeed MMC host controller on Amlogic SoCs provides an interface
+for MMC, SD, SDIO and SDHC types of memory cards.
+
+Supported maximum speeds are the ones of the eMMC standard 4.41 as well
+as the speed of SD standard 2.0.
+

Documentation/devicetree/bindings/mmc/meson-mmc.txt line 18

Quoted 10 lines
Documentation/devicetree/bindings/mmc/meson-mmc.txt new file +10 -0
+Required properties:
+ - compatible : "amlogic,meson-mmc"
+ - reg : mmc controller base registers
+ - interrupts : mmc controller interrupt
+ - clocks : phandle to clock provider
+ - pinctrl-names : should contain "sdio_a" or "sdio_b"
+ - pinctrl-0: Should specify pin control groups used for this controller
+
+Optional properties:
+ - meson,sd-port : 0 for port A, 1 for port B

This is different than the pinctrl-names? It needs a better description including what is the default if absent.

Quoted 15 lines
Documentation/devicetree/bindings/mmc/meson-mmc.txt new file +12 -0
+ - for cd, bus-width and additional generic mmc parameters
+   please refer to mmc.txt within this directory
+
+Examples:
+	mmc0: mmc at c1108c20 {
+		pinctrl-names = "sdio_b";
+		pinctrl-0 = <&mmc0_sd_b_pins>;
+		compatible = "amlogic,meson-mmc";
+		reg = <0xc1108c20 0x20>;
+		interrupts = <0 28 1>;
+		clocks = <&clkc CLKID_CLK81>;
+	};
Signature · 1 line
1.9.1
#3 lore raw

PATCH v5 1/4 mmc: meson: Document Amlogic Meson MMC DT bindings

Quoted 28 lines · Rob Herring
Quoted 27 lines · Carlo Caione

From: Carlo Caione <[email protected]>

---
 .../devicetree/bindings/mmc/meson-mmc.txt          | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/meson-mmc.txt
Documentation/devicetree/bindings/mmc/meson-mmc.txt new file +13 -0
new file mode 100644
index 0000000..328157e
@@ -0,0 +1,30 @@
+* Amlogic Meson MMC controller
+
+The highspeed MMC host controller on Amlogic SoCs provides an interface
+for MMC, SD, SDIO and SDHC types of memory cards.
+
+Supported maximum speeds are the ones of the eMMC standard 4.41 as well
+as the speed of SD standard 2.0.
+
+Required properties:
+ - compatible : "amlogic,meson-mmc"
+ - reg : mmc controller base registers
+ - interrupts : mmc controller interrupt
+ - clocks : phandle to clock provider
Quoted 9 lines

Documentation/devicetree/bindings/mmc/meson-mmc.txt line 18

Quoted 5 lines
Documentation/devicetree/bindings/mmc/meson-mmc.txt new file +5 -0
+ - pinctrl-names : should contain "sdio_a" or "sdio_b"
+ - pinctrl-0: Should specify pin control groups used for this controller
+
+Optional properties:
+ - meson,sd-port : 0 for port A, 1 for port B

This is different than the pinctrl-names? It needs a better description including what is the default if absent.

This was already discussed here
http://www.spinics.net/lists/linux-mmc/msg34407.html.
In the previous version (V4) I used pinctrl-names to select the correct port but discussing with Ulf we decided to switch back to have a new property in the DTS.
About what this value is, it is a bit up to our interpretation. We use this value to setup the SDIO_PORT_SEL register and in the register description in the documentation I read only "SDIO port selection. 0:
SDIO A; 1: SDIO B".
So I'm assuming this is somehow related to the muxing / pin controller configuration but probably it's better to stay on the safe side and just have a new property to setup this value.

I'll add the new default value in the next version.

Signature · 1 line
Carlo Caione
#4 lore raw

PATCH v5 2/4 mmc: meson: Add driver for the SD/MMC host found on Amlogic Meson SoCs

In reply to Carlo Caione

From: Carlo Caione <[email protected]>

Add a driver for the SD/MMC host found on the Amlogic Meson SoCs. This is an MMC controller which provides an interface between the application processor and various memory cards. It supports the SD specification v2.0 and the eMMC specification v4.41.

---

Ulf,
I addressed all your suggestions but the command timeout is still not implemented. I'm having some trouble trying to figure out how the timeout registers really work and how to integrate this hw timeout in the driver. This is not really a problem for the platforms we currently support and the driver works fairly well already.

---
 drivers/mmc/host/Kconfig     |   7 +
 drivers/mmc/host/Makefile    |   1 +
 drivers/mmc/host/meson-mmc.c | 535 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 543 insertions(+)
 create mode 100644 drivers/mmc/host/meson-mmc.c
drivers/mmc/host/Kconfig +7 -0
index 1526b8a..99e0a0d 100644
@@ -766,6 +766,13 @@ config MMC_REALTEK_USB
 	  Say Y here to include driver code to support SD/MMC card interface
 	  of Realtek RTS5129/39 series card reader
 
+config MMC_MESON
+	tristate "Amlogic Meson SD/MMC Host Controller support"
+	depends on ARCH_MESON
+	help
+	  This selects support for the SD/MMC Host Controller on
+	  Amlogic Meson SoCs.
+
 config MMC_SUNXI
 	tristate "Allwinner sunxi SD/MMC Host Controller support"
 	depends on ARCH_SUNXI
drivers/mmc/host/Makefile +1 -0
index 3595f83..26ddf76 100644
@@ -54,6 +54,7 @@ obj-$(CONFIG_MMC_VUB300)	+= vub300.o
 obj-$(CONFIG_MMC_USHC)		+= ushc.o
 obj-$(CONFIG_MMC_WMT)		+= wmt-sdmmc.o
 obj-$(CONFIG_MMC_MOXART)	+= moxart-mmc.o
+obj-$(CONFIG_MMC_MESON)		+= meson-mmc.o
 obj-$(CONFIG_MMC_SUNXI)		+= sunxi-mmc.o
 obj-$(CONFIG_MMC_USDHI6ROL0)	+= usdhi6rol0.o
 obj-$(CONFIG_MMC_TOSHIBA_PCI)	+= toshsd.o
drivers/mmc/host/meson-mmc.c new file +535 -0

535 lines not on this page · raw message

Signature · 1 line
1.9.1
#5 lore raw

PATCH v5 2/4 mmc: meson: Add driver for the SD/MMC host found on Amlogic Meson SoCs

Hi Carlo,

Am 27.02.2016 um 19:01 schrieb Carlo Caione:

Quoted 6 lines

Add a driver for the SD/MMC host found on the Amlogic Meson SoCs. This is an MMC controller which provides an interface between the application processor and various memory cards. It supports the SD specification v2.0 and the eMMC specification v4.41.

Enabling this driver on top of my v2 arm64 gxbb series, I get:

CC drivers/mmc/host/meson-mmc.o
drivers/mmc/host/meson-mmc.c: In function 'meson_mmc_probe':
drivers/mmc/host/meson-mmc.c:471:12: error: implicit declaration of function 'devm_pinctrl_get' [-Werror=implicit-function-declaration]

  pinctrl = devm_pinctrl_get(&pdev->dev);
            ^
drivers/mmc/host/meson-mmc.c:471:10: warning: assignment makes pointer
from integer without a cast [-Wint-conversion]
  pinctrl = devm_pinctrl_get(&pdev->dev);
          ^

cc1: some warnings being treated as errors scripts/Makefile.build:258: recipe for target 'drivers/mmc/host/meson-mmc.o' failed
make[3]: *** [drivers/mmc/host/meson-mmc.o] Error 1 scripts/Makefile.build:407: recipe for target 'drivers/mmc/host' failed make[2]: *** [drivers/mmc/host] Error 2 scripts/Makefile.build:407: recipe for target 'drivers/mmc' failed make[1]: *** [drivers/mmc] Error 2
Makefile:959: recipe for target 'drivers' failed
make: *** [drivers] Error 2

Either this is missing a Kconfig dependency on PINCTRL, or should be using #ifdef CONFIG_PINCTRL or some other guard.

For gxbb we could just ignore this in the hopes that Nicolas will have a working pinctrl driver soon, but it might reappear for COMPILE_TEST.

Regards,
Andreas

Signature · 2 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton; HRB 21284 (AG N?rnberg)
#6 lore raw

PATCH v5 2/4 mmc: meson: Add driver for the SD/MMC host found on Amlogic Meson SoCs

Quoted 33 lines · Andreas F?rber

Hi Carlo,

Am 27.02.2016 um 19:01 schrieb Carlo Caione:

Quoted 6 lines

Add a driver for the SD/MMC host found on the Amlogic Meson SoCs. This is an MMC controller which provides an interface between the application processor and various memory cards. It supports the SD specification v2.0 and the eMMC specification v4.41.

Enabling this driver on top of my v2 arm64 gxbb series, I get:

CC drivers/mmc/host/meson-mmc.o
drivers/mmc/host/meson-mmc.c: In function 'meson_mmc_probe':
drivers/mmc/host/meson-mmc.c:471:12: error: implicit declaration of function 'devm_pinctrl_get' [-Werror=implicit-function-declaration]

  pinctrl = devm_pinctrl_get(&pdev->dev);
            ^
drivers/mmc/host/meson-mmc.c:471:10: warning: assignment makes pointer
from integer without a cast [-Wint-conversion]
  pinctrl = devm_pinctrl_get(&pdev->dev);
          ^

cc1: some warnings being treated as errors scripts/Makefile.build:258: recipe for target 'drivers/mmc/host/meson-mmc.o' failed
make[3]: *** [drivers/mmc/host/meson-mmc.o] Error 1 scripts/Makefile.build:407: recipe for target 'drivers/mmc/host' failed make[2]: *** [drivers/mmc/host] Error 2 scripts/Makefile.build:407: recipe for target 'drivers/mmc' failed make[1]: *** [drivers/mmc] Error 2
Makefile:959: recipe for target 'drivers' failed
make: *** [drivers] Error 2

Quoted 2 lines

Either this is missing a Kconfig dependency on PINCTRL, or should be using #ifdef CONFIG_PINCTRL or some other guard.

I think that we can actually drop the whole devm_pinctrl_get(). I'll wait for some comments from Ulf before submitting a fix.

Quoted 2 lines

For gxbb we could just ignore this in the hopes that Nicolas will have a working pinctrl driver soon, but it might reappear for COMPILE_TEST.

AFAIR from a discussion with Amlogic it seems that they totally changed the SD controller in the S905 so probably we will need a new driver for the gxbb. At this point I also wonder if it's not worthy it already to change the compatible for this driver to something more specific for Meson8 / Meson8b.
Probably we will have some more news when the documentation will be available.

Thank you for testing this,

Signature · 1 line
Carlo Caione
#7 lore raw

PATCH v5 2/4 mmc: meson: Add driver for the SD/MMC host found on Amlogic Meson SoCs

In reply to Carlo Caione
Quoted 8 lines · Carlo Caione

From: Carlo Caione <[email protected]>

Add a driver for the SD/MMC host found on the Amlogic Meson SoCs. This is an MMC controller which provides an interface between the application processor and various memory cards. It supports the SD specification v2.0 and the eMMC specification v4.41.

Sorry for the delay.

Apparently this slipped through my mmc mail filters, as I think you forgotten to post this to linux-mmc.

[...]

drivers/mmc/host/meson-mmc.c line 241

Quoted 9 lines
drivers/mmc/host/meson-mmc.c new file +9 -0
+static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+       struct meson_mmc_host *host = mmc_priv(mmc);
+       struct mmc_command *cmd = mrq->cmd;
+       struct mmc_data *data = mrq->data;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&host->lock, flags);

I would advise you to re-visit the deployment of the locking in this driver. It doesn't seem correct.

For example, keeping IRQ disabled while mapping DMA buffers isn't a good idea, as it may cause the IRQs to be disabled for quite a while.

Quoted 28 lines
drivers/mmc/host/meson-mmc.c new file +28 -0
+
+       if (host->error) {
+               cmd->error = host->error;
+               spin_unlock_irqrestore(&host->lock, flags);
+               mmc_request_done(mmc, mrq);
+               return;
+       }
+
+       if (data) {
+               ret = meson_mmc_map_dma(host, data, data->flags);
+               if (ret < 0) {
+                       dev_err(mmc_dev(mmc), "map DMA failed\n");
+                       cmd->error = ret;
+                       data->error = ret;
+                       spin_unlock_irqrestore(&host->lock, flags);
+                       mmc_request_done(mmc, mrq);
+                       return;
+               }
+               writel(sg_dma_address(data->sg), host->base + SDIO_ADDR);
+       }
+
+       host->mrq = mrq;
+       meson_mmc_start_cmd(mmc, mrq->cmd);
+
+       spin_unlock_irqrestore(&host->lock, flags);
+
+       schedule_delayed_work(&host->timeout_work, host->timeout);
+}

drivers/mmc/host/meson-mmc.c line 279

Quoted 10 lines
drivers/mmc/host/meson-mmc.c new file +10 -0
+
+static irqreturn_t meson_mmc_irq(int irq, void *data)
+{
+       struct meson_mmc_host *host = (void *) data;
+       struct mmc_request *mrq = host->mrq;
+       u32 irqs;
+
+       irqs = readl(host->base + SDIO_IRQS);
+       if (mrq && (irqs & REG_IRQS_CMD_INT))
+               return IRQ_WAKE_THREAD;

As you don't use the IRQF_ONESHOT flag, this hard IRQ handler may be invoked while the threaded handler runs.

Although, I don't see any protection of the host->mrq pointer etc, don't you need that?

Quoted 27 lines
drivers/mmc/host/meson-mmc.c new file +27 -0
+
+       return IRQ_HANDLED;
+}
+
+void meson_mmc_read_response(struct meson_mmc_host *host)
+{
+       struct mmc_command *cmd = host->mrq->cmd;
+       u32 mult;
+       int i, resp[4] = { 0 };
+
+       mult = readl(host->base + SDIO_MULT);
+       mult |= REG_MULT_WR_RD_OUT_IND;
+       mult &= ~(REG_MULT_RD_INDEX_M << REG_MULT_RD_INDEX_S);
+       writel(mult, host->base + SDIO_MULT);
+
+       if (cmd->flags & MMC_RSP_136) {
+               for (i = 0; i <= 3; i++)
+                       resp[3 - i] = readl(host->base + SDIO_ARGU);
+               cmd->resp[0] = (resp[0] << 8) | ((resp[1] >> 24) & 0xff);
+               cmd->resp[1] = (resp[1] << 8) | ((resp[2] >> 24) & 0xff);
+               cmd->resp[2] = (resp[2] << 8) | ((resp[3] >> 24) & 0xff);
+               cmd->resp[3] = (resp[3] << 8);
+       } else if (cmd->flags & MMC_RSP_PRESENT) {
+               cmd->resp[0] = readl(host->base + SDIO_ARGU);
+       }
+}
+

drivers/mmc/host/meson-mmc.c line 316

Quoted 10 lines
drivers/mmc/host/meson-mmc.c new file +10 -0
+static irqreturn_t meson_mmc_irq_thread(int irq, void *irq_data)
+{
+       struct meson_mmc_host *host = (void *) irq_data;
+       struct mmc_data *data;
+       unsigned long flags;
+       struct mmc_request *mrq;
+       u32 irqs, send;
+
+       cancel_delayed_work_sync(&host->timeout_work);
+       spin_lock_irqsave(&host->lock, flags);

You are disabling IRQs during the entire execution of this threaded IRQ handler, that's not a good behaviour as it may be disabled for quite a while.

Although, perhaps you do this to avoid needing to protect host->mrq in the hard IRQ handler!?

Quoted 51 lines
drivers/mmc/host/meson-mmc.c new file +51 -0
+
+       mrq = host->mrq;
+       data = mrq->data;
+
+       if (!mrq) {
+               spin_unlock_irqrestore(&host->lock, flags);
+               return IRQ_HANDLED;
+       }
+
+       if (host->cmd_is_stop)
+               goto out;
+
+       irqs = readl(host->base + SDIO_IRQS);
+       send = readl(host->base + SDIO_SEND);
+
+       mrq->cmd->error = 0;
+
+       if (!data) {
+               if (!((irqs & REG_IRQS_RESP_CRC7) ||
+                     (send & REG_SEND_RESP_NO_CRC7)))
+                       mrq->cmd->error = -EILSEQ;
+               else
+                       meson_mmc_read_response(host);
+       } else {
+               if (!((irqs & REG_IRQS_RD_CRC16) ||
+                     (irqs & REG_IRQS_WR_CRC16))) {
+                       mrq->cmd->error = -EILSEQ;
+               } else {
+                       data->bytes_xfered = data->blksz * data->blocks;
+                       dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+                                    ((data->flags & MMC_DATA_READ) ?
+                                    DMA_FROM_DEVICE : DMA_TO_DEVICE));
+               }
+       }
+
+       if (mrq->stop) {
+               host->cmd_is_stop = true;
+               meson_mmc_start_cmd(host->mmc, mrq->stop);
+               spin_unlock_irqrestore(&host->lock, flags);
+               return IRQ_HANDLED;
+       }
+
+out:
+       host->cmd_is_stop = false;
+       host->mrq = NULL;
+       spin_unlock_irqrestore(&host->lock, flags);
+       mmc_request_done(host->mmc, mrq);
+
+       return IRQ_HANDLED;
+}
+

[...]

Quoted 24 lines
drivers/mmc/host/meson-mmc.c new file +24 -0
+static int meson_mmc_probe(struct platform_device *pdev)
+{
+       struct mmc_host *mmc;
+       struct meson_mmc_host *host;
+       struct pinctrl *pinctrl;
+       struct resource *res;
+       int ret, irq;
+       u32 port;
+
+       mmc = mmc_alloc_host(sizeof(struct meson_mmc_host), &pdev->dev);
+       if (!mmc) {
+               dev_err(&pdev->dev, "mmc alloc host failed\n");
+               return -ENOMEM;
+       }
+
+       host = mmc_priv(mmc);
+       host->mmc = mmc;
+       host->timeout = msecs_to_jiffies(10000);
+       host->port = 0;
+
+       if (!of_property_read_u32(pdev->dev.of_node, "meson,sd-port", &port))
+               host->port = port;
+
+

drivers/mmc/host/meson-mmc.c line 436

Quoted 10 lines
drivers/mmc/host/meson-mmc.c new file +10 -0
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       host->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(host->base)) {
+               ret = PTR_ERR(host->base);
+               goto error_free_host;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       ret = devm_request_threaded_irq(&pdev->dev, irq, meson_mmc_irq,
+                                       meson_mmc_irq_thread, 0, "meson_mmc",

Is the IRQs level or edge triggered? In other words, will the hard IRQ handler miss IRQs if you use IRQF_ONESHOT?

Quoted 53 lines
drivers/mmc/host/meson-mmc.c new file +53 -0
+                                       host);
+       if (ret)
+               goto error_free_host;
+
+       host->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(host->clk)) {
+               ret = PTR_ERR(host->clk);
+               goto error_free_host;
+       }
+
+       ret = clk_prepare_enable(host->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Enable clk error %d\n", ret);
+               goto error_free_host;
+       }
+
+       /* we do not support scatter lists in hardware */
+       mmc->max_segs = 1;
+       mmc->max_req_size = SDIO_BOUNCE_REQ_SIZE;
+       mmc->max_seg_size = mmc->max_req_size;
+       mmc->max_blk_count = 256;
+       mmc->max_blk_size = mmc->max_req_size / mmc->max_blk_count;
+       mmc->f_min = 300000;
+       mmc->f_max = 50000000;
+       mmc->caps |= MMC_CAP_4_BIT_DATA;
+       mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
+       mmc->caps2 |= MMC_CAP2_NO_SDIO;
+       mmc->ocr_avail = MMC_VDD_33_34;
+       mmc->ops = &meson_mmc_ops;
+
+       spin_lock_init(&host->lock);
+
+       INIT_DELAYED_WORK(&host->timeout_work, meson_mmc_timeout);
+
+       pinctrl = devm_pinctrl_get(&pdev->dev);
+       if (IS_ERR(pinctrl)) {
+               ret = PTR_ERR(pinctrl);
+               goto error;
+       }
+
+       ret = mmc_of_parse(mmc);
+       if (ret)
+               goto error;
+
+       platform_set_drvdata(pdev, mmc);
+
+       ret = mmc_add_host(mmc);
+       if (ret)
+               goto error;
+
+       dev_info(&pdev->dev, "base:0x%p irq:%u port:%u\n",
+                host->base, irq, host->port);
+

drivers/mmc/host/meson-mmc.c line 499

Quoted 10 lines
drivers/mmc/host/meson-mmc.c new file +10 -0
+       return 0;
+
+error:
+       clk_disable_unprepare(host->clk);
+error_free_host:
+       mmc_free_host(mmc);
+
+       return ret;
+}
+

[...]

Kind regards
Uffe

#8 lore raw

PATCH v5 3/4 ARM: dts: meson8b: Add MMC nodes

In reply to Carlo Caione

From: Carlo Caione <[email protected]>

Enable the MMC for the Meson8b platforms.

---
 arch/arm/boot/dts/meson8b-mxq.dts      |  8 ++++++++
 arch/arm/boot/dts/meson8b-odroidc1.dts |  8 ++++++++
 arch/arm/boot/dts/meson8b.dtsi         | 16 ++++++++++++++++
 3 files changed, 32 insertions(+)
arch/arm/boot/dts/meson8b-mxq.dts +8 -0
index c7fdaea..5c533a6 100644
@@ -60,6 +60,14 @@
 	};
 };
 
+&mmc0 {
+	status = "okay";
+	pinctrl-names = "sdio_b";
+	pinctrl-0 = <&mmc0_sd_b_pins>;
+	meson,sd-port = <1>;
+	broken-cd;
+};
+
 &uart_AO {
 	status = "okay";
 	pinctrl-0 = <&uart_ao_a_pins>;
arch/arm/boot/dts/meson8b-odroidc1.dts +8 -0
index e50f1a1..a060c84 100644
@@ -71,6 +71,14 @@
 	};
 };
 
+&mmc0 {
+	status = "okay";
+	pinctrl-names = "sdio_b";
+	pinctrl-0 = <&mmc0_sd_b_pins>;
+	meson,sd-port = <1>;
+	broken-cd;
+};
+
 &uart_AO {
 	status = "okay";
 	pinctrl-0 = <&uart_ao_a_pins>;
arch/arm/boot/dts/meson8b.dtsi +16 -0
index 8bad557..25d795c 100644
@@ -187,6 +187,22 @@
 					function = "uart_ao";
 				};
 			};
+
+			mmc0_sd_b_pins: mmc0_sd_b {
+				mux {
+					groups = "sd_d1_b", "sd_d0_b", "sd_clk_b", "sd_cmd_b",
+						 "sd_d3_b", "sd_d2_b";
+					function = "sd_b";
+				};
+			};
+		};
+
+		mmc0: mmc at c1108c20 {
+			compatible = "amlogic,meson-mmc";
+			reg = <0xc1108c20 0x20>;
+			interrupts = <0 28 1>;
+			clocks = <&clkc CLKID_CLK81>;
+			status = "disabled";
 		};
 	};
 }; /* end of / */
Signature · 1 line
1.9.1
maintainer
#9 lore raw

PATCH v5 3/4 ARM: dts: meson8b: Add MMC nodes

Hi Carlo,

Quoted 5 lines · Carlo Caione

From: Carlo Caione <[email protected]>

Enable the MMC for the Meson8b platforms.

[...]

Quoted 6 lines
arch/arm/boot/dts/meson8b.dtsi +0 -0
index 8bad557..25d795c 100644
@@ -187,6 +187,22 @@
 					function = "uart_ao";

arch/arm/boot/dts/meson8b.dtsi line 197

Quoted 10 lines
arch/arm/boot/dts/meson8b.dtsi +8 -0
 				};
 			};
+
+			mmc0_sd_b_pins: mmc0_sd_b {
+				mux {
+					groups = "sd_d1_b", "sd_d0_b", "sd_clk_b", "sd_cmd_b",
+						 "sd_d3_b", "sd_d2_b";
+					function = "sd_b";
+				};
+			};

These pins are added under pinctrl_aobus, but in the pinctrl driver, they're under cbus. If I move this into the pinctrl_cbus node, I get it to work on my odroid-c1, and am able to mount/use an MMC rootfs.

Kevin

#10 lore raw

PATCH v5 3/4 ARM: dts: meson8b: Add MMC nodes

Quoted 24 lines · Kevin Hilman

Hi Carlo,

Quoted 5 lines · Carlo Caione

From: Carlo Caione <[email protected]>

Enable the MMC for the Meson8b platforms.

[...]

Quoted 12 lines
arch/arm/boot/dts/meson8b.dtsi +4 -0
index 8bad557..25d795c 100644
@@ -187,6 +187,22 @@
                                      function = "uart_ao";
                              };
                      };
+
+                     mmc0_sd_b_pins: mmc0_sd_b {
+                             mux {
+                                     groups = "sd_d1_b", "sd_d0_b", "sd_clk_b", "sd_cmd_b",
Quoted 8 lines

arch/arm/boot/dts/meson8b.dtsi line 197

Quoted 4 lines
arch/arm/boot/dts/meson8b.dtsi +4 -0
+                                              "sd_d3_b", "sd_d2_b";
+                                     function = "sd_b";
+                             };
+                     };

These pins are added under pinctrl_aobus, but in the pinctrl driver, they're under cbus. If I move this into the pinctrl_cbus node, I get it to work on my odroid-c1, and am able to mount/use an MMC rootfs.

Ouch, thank you for pointing this out, I'll fix it in v6.

thanks,

Signature · 1 line
Carlo Caione
#11 lore raw

PATCH v5 4/4 ARM: multi_v7_defconfig: Add Amlogic Meson MMC support

In reply to Carlo Caione

From: Carlo Caione <[email protected]>

---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/configs/multi_v7_defconfig +1 -0
index 314f6be..113b234 100644
@@ -633,6 +633,7 @@ CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_PLTFM=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_MESON=y
 CONFIG_MMC_SH_MMCIF=y
 CONFIG_MMC_SUNXI=y
 CONFIG_NEW_LEDS=y
Signature · 1 line
1.9.1