Skip to contentSkip to conversation

mmc: sunxi: Make sample clocks optional

PATCH Superseded Hans de Goede 4 participants 9 messages Jul 16, 2016 – Jul 30, 2016

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover mmc: sunxi: Make sample clocks optional

Hi All,

It turns out that sun4i / sun5i do not have sample clocks at all, so make them optional. Also remove the DDR capability when there are no sample clocks because DDR modes do not work reliably without them (observed on an UTOO P66 tablet with eMMC).

Ulf, can you please merge the first 2 patches, patches 3-4 should be merged through Maxime's sunxi/dts tree, but not before the first 2 have hit linux-next.

Regards,

Hans

#1 lore raw

PATCH 1/4 mmc: sunxi: Disable sample clks on remove

When support for the sample clks was added calls to prepare_enable were added to the probe path, but matching calls to disable_unprepare were forgotten in the remove path, this fixes this.

---
 drivers/mmc/host/sunxi-mmc.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/mmc/host/sunxi-mmc.c +2 -0
index a4d2b63..71a480b 100644
@@ -1160,6 +1160,8 @@ static int sunxi_mmc_remove(struct platform_device *pdev)
 	if (!IS_ERR(host->reset))
 		reset_control_assert(host->reset);
 
+	clk_disable_unprepare(host->clk_sample);
+	clk_disable_unprepare(host->clk_output);
 	clk_disable_unprepare(host->clk_mmc);
 	clk_disable_unprepare(host->clk_ahb);
 
Signature · 1 line
2.7.4
#2 lore raw

PATCH 2/4 mmc: sunxi: Make sample clocks optional

In reply to Hans de Goede

It turns out that sun4i (A10) and sun5i (A13 & co) do not have sample clocks, so make them optional.

Since these do not have sample clocks, they cannot (reliably) do DDR rates, so only set MMC_CAP_1_8V_DDR when we do have sample clks.

Note this patch only changes the devm_clk_get error checking and sets the clocks to NULL if they don't exists. All the clk_foo calls accept a NULL clk and will return success when called with a NULL clk, so this is all that is necessary.

---
 drivers/mmc/host/sunxi-mmc.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/mmc/host/sunxi-mmc.c +13 -5
index 71a480b..4552ee0 100644
@@ -1016,14 +1016,20 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
 
 	host->clk_output = devm_clk_get(&pdev->dev, "output");
 	if (IS_ERR(host->clk_output)) {
-		dev_err(&pdev->dev, "Could not get output clock\n");
-		return PTR_ERR(host->clk_output);
+		if (PTR_ERR(host->clk_output) != -ENOENT) {
+			dev_err(&pdev->dev, "Could not get output clock\n");
+			return PTR_ERR(host->clk_output);
+		}
+		host->clk_output = NULL;
 	}
 
 	host->clk_sample = devm_clk_get(&pdev->dev, "sample");
 	if (IS_ERR(host->clk_sample)) {
-		dev_err(&pdev->dev, "Could not get sample clock\n");
-		return PTR_ERR(host->clk_sample);
+		if (PTR_ERR(host->clk_sample) != -ENOENT) {
+			dev_err(&pdev->dev, "Could not get sample clock\n");
+			return PTR_ERR(host->clk_sample);
+		}
+		host->clk_sample = NULL;
 	}
 
 	host->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
@@ -1126,9 +1132,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
 	mmc->f_min		=   400000;
 	mmc->f_max		= 52000000;
 	mmc->caps	       |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-				  MMC_CAP_1_8V_DDR |
 				  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 
+	if (host->clk_output && host->clk_sample)
+		mmc->caps      |= MMC_CAP_1_8V_DDR;
+
 	ret = mmc_of_parse(mmc);
 	if (ret)
 		goto error_free_dma;
Signature · 1 line
2.7.4
#3 lore raw

PATCH 2/4 mmc: sunxi: Make sample clocks optional

Quoted 21 lines · Hans de Goede

It turns out that sun4i (A10) and sun5i (A13 & co) do not have sample clocks, so make them optional.

Since these do not have sample clocks, they cannot (reliably) do DDR rates, so only set MMC_CAP_1_8V_DDR when we do have sample clks.

Note this patch only changes the devm_clk_get error checking and sets the clocks to NULL if they don't exists. All the clk_foo calls accept a NULL clk and will return success when called with a NULL clk, so this is all that is necessary.

---
 drivers/mmc/host/sunxi-mmc.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/mmc/host/sunxi-mmc.c +0 -0
index 71a480b..4552ee0 100644

drivers/mmc/host/sunxi-mmc.c static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, · line 1019

Quoted 6 lines
drivers/mmc/host/sunxi-mmc.c +1 -2
@@ -1016,14 +1016,20 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
 
        host->clk_output = devm_clk_get(&pdev->dev, "output");
        if (IS_ERR(host->clk_output)) {
-               dev_err(&pdev->dev, "Could not get output clock\n");
-               return PTR_ERR(host->clk_output);
+               if (PTR_ERR(host->clk_output) != -ENOENT) {

This is new to me for how to implement support for optional clocks.

Is this how the clock maintainer think it should be implemented?

Quoted 32 lines
drivers/mmc/host/sunxi-mmc.c +12 -4
+                       dev_err(&pdev->dev, "Could not get output clock\n");
+                       return PTR_ERR(host->clk_output);
+               }
+               host->clk_output = NULL;
        }
 
        host->clk_sample = devm_clk_get(&pdev->dev, "sample");
        if (IS_ERR(host->clk_sample)) {
-               dev_err(&pdev->dev, "Could not get sample clock\n");
-               return PTR_ERR(host->clk_sample);
+               if (PTR_ERR(host->clk_sample) != -ENOENT) {
+                       dev_err(&pdev->dev, "Could not get sample clock\n");
+                       return PTR_ERR(host->clk_sample);
+               }
+               host->clk_sample = NULL;
        }
 
        host->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
@@ -1126,9 +1132,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
        mmc->f_min              =   400000;
        mmc->f_max              = 52000000;
        mmc->caps              |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                                 MMC_CAP_1_8V_DDR |
                                  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 
+       if (host->clk_output && host->clk_sample)
+               mmc->caps      |= MMC_CAP_1_8V_DDR;
+
        ret = mmc_of_parse(mmc);
        if (ret)
                goto error_free_dma;
--
Quoted 2 lines

2.7.4

Kind regards
Uffe

#4 lore raw

PATCH 2/4 mmc: sunxi: Make sample clocks optional

In reply to Hans de Goede

Hi,

Quoted 10 lines · Hans de Goede

It turns out that sun4i (A10) and sun5i (A13 & co) do not have sample clocks, so make them optional.

Since these do not have sample clocks, they cannot (reliably) do DDR rates, so only set MMC_CAP_1_8V_DDR when we do have sample clks.

Note this patch only changes the devm_clk_get error checking and sets the clocks to NULL if they don't exists. All the clk_foo calls accept a NULL clk and will return success when called with a NULL clk, so this is all that is necessary.

The clocks aren't really optional. They're not needed for the A10 / A13, and mandatory for the A20 and later.

Having a new compatible for the A20 that would require that clock and not require it for the A10/A13 anymore seems more appropriate.

Maxime

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160725/dfdb0ee7/attachment-0001.sig>
#5 lore raw

PATCH 2/4 mmc: sunxi: Make sample clocks optional

Hi,

Quoted 14 lines · Maxime Ripard

Hi,

Quoted 10 lines · Hans de Goede

It turns out that sun4i (A10) and sun5i (A13 & co) do not have sample clocks, so make them optional.

Since these do not have sample clocks, they cannot (reliably) do DDR rates, so only set MMC_CAP_1_8V_DDR when we do have sample clks.

Note this patch only changes the devm_clk_get error checking and sets the clocks to NULL if they don't exists. All the clk_foo calls accept a NULL clk and will return success when called with a NULL clk, so this is all that is necessary.

Quoted 5 lines

The clocks aren't really optional. They're not needed for the A10 / A13, and mandatory for the A20 and later.

Having a new compatible for the A20 that would require that clock and not require it for the A10/A13 anymore seems more appropriate.

Ok, I've prepared a new version using a new compatible.

Regards,

Hans

#6 lore raw

PATCH 3/4 ARM: dts: sun4i: Remove sample clocks from mmc host nodes

In reply to Hans de Goede

It turns out the A10 does not have mmc sample clocks (the bits for this in the register always read back 0, not listed in the datasheet), so remove the sample clocks from the mmc host nodes.

---
 arch/arm/boot/dts/sun4i-a10.dtsi | 32 ++++++++------------------------
 1 file changed, 8 insertions(+), 24 deletions(-)
arch/arm/boot/dts/sun4i-a10.dtsi +8 -24
index 7e7dfc2..f6bf851 100644
@@ -783,13 +783,9 @@
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c0f000 0x1000>;
 			clocks = <&ahb_gates 8>,
-				 <&mmc0_clk 0>,
-				 <&mmc0_clk 1>,
-				 <&mmc0_clk 2>;
+				 <&mmc0_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <32>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -800,13 +796,9 @@
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c10000 0x1000>;
 			clocks = <&ahb_gates 9>,
-				 <&mmc1_clk 0>,
-				 <&mmc1_clk 1>,
-				 <&mmc1_clk 2>;
+				 <&mmc1_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <33>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -817,13 +809,9 @@
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c11000 0x1000>;
 			clocks = <&ahb_gates 10>,
-				 <&mmc2_clk 0>,
-				 <&mmc2_clk 1>,
-				 <&mmc2_clk 2>;
+				 <&mmc2_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <34>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -834,13 +822,9 @@
 			compatible = "allwinner,sun4i-a10-mmc";
 			reg = <0x01c12000 0x1000>;
 			clocks = <&ahb_gates 11>,
-				 <&mmc3_clk 0>,
-				 <&mmc3_clk 1>,
-				 <&mmc3_clk 2>;
+				 <&mmc3_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <35>;
 			status = "disabled";
 			#address-cells = <1>;
Signature · 1 line
2.7.4
#7 lore raw

PATCH 4/4 ARM: dts: sun5i: Remove sample clocks from mmc host nodes

In reply to Hans de Goede

It turns out that sun5i does not have mmc sample clocks (the bits for this in the register always read back 0, not listed in the datasheet), so remove the sample clocks from the mmc host nodes.

---
 arch/arm/boot/dts/sun5i.dtsi | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)
arch/arm/boot/dts/sun5i.dtsi +6 -18
index e374f4f..86044f9 100644
@@ -431,13 +431,9 @@
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
 			clocks = <&ahb_gates 8>,
-				 <&mmc0_clk 0>,
-				 <&mmc0_clk 1>,
-				 <&mmc0_clk 2>;
+				 <&mmc0_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <32>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -448,13 +444,9 @@
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
 			clocks = <&ahb_gates 9>,
-				 <&mmc1_clk 0>,
-				 <&mmc1_clk 1>,
-				 <&mmc1_clk 2>;
+				 <&mmc1_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <33>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -465,13 +457,9 @@
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
 			clocks = <&ahb_gates 10>,
-				 <&mmc2_clk 0>,
-				 <&mmc2_clk 1>,
-				 <&mmc2_clk 2>;
+				 <&mmc2_clk 0>;
 			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+				      "mmc";
 			interrupts = <34>;
 			status = "disabled";
 			#address-cells = <1>;
Signature · 1 line
2.7.4
#8 lore raw

cover mmc: sunxi: Make sample clocks optional

In reply to Hans de Goede

16.07.2016, 18:50, "Hans de Goede" <[email protected]>:

Quoted 11 lines

Hi All,

It turns out that sun4i / sun5i do not have sample clocks at all, so make them optional. Also remove the DDR capability when there are no sample clocks because DDR modes do not work reliably without them (observed on an UTOO P66 tablet with eMMC).

Ulf, can you please merge the first 2 patches, patches 3-4 should be merged through Maxime's sunxi/dts tree, but not before the first 2 have hit linux-next.

Quoted 8 lines

Regards,

Hans

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Interesting...

A64 have also no external sample/output clock... (The sample/output clock is integrated into MMC IP core now)