Skip to contentSkip to conversation

atmel-mci fixes

PATCH Superseded ludovic.desroches at atmel.com 4 participants 14 messages Mar 21, 2012 – Apr 2, 2012

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

cover atmel-mci fixes

Hi,

The following patches provide some fixes for atmel-mci driver:
- data timeout calculation was not correct and can cause serious issues when using a rootfs on the sd card.
- the r/w proof features is available only from 2xx hsmci version
- supports for odd clock dividers available from 5xx hsmci version

Regards

Ludovic

#1 lore raw

PATCH 1/3 mmc: atmel-mci: correct data timeout computation

From: Ludovic Desroches <[email protected]>

The HSMCI operates at a rate of up to Master Clock divided by two.

---
 drivers/mmc/host/atmel-mci.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/mmc/host/atmel-mci.c +1 -1
index e4449a5..e161452 100644
@@ -480,7 +480,7 @@ err:
 static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
 					unsigned int ns)
 {
-	return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+	return (ns * ((host->bus_hz/2) / 1000000) + 999) / 1000;
 }
 
 static void atmci_set_timeout(struct atmel_mci *host,
Signature · 1 line
1.7.5.4
#2 lore raw

PATCH 1/3 mmc: atmel-mci: correct data timeout computation

Hello.

Quoted 14 lines · On 03/21/2012 06:41 PM, [email protected] wrote:

From: Ludovic Desroches<[email protected]>

The HSMCI operates at a rate of up to Master Clock divided by two.

---
  drivers/mmc/host/atmel-mci.c |    2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
drivers/mmc/host/atmel-mci.c +0 -0
index e4449a5..e161452 100644

drivers/mmc/host/atmel-mci.c err: · line 483

Quoted 5 lines
drivers/mmc/host/atmel-mci.c +1 -1
@@ -480,7 +480,7 @@ err:
  static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
  					unsigned int ns)
  {
-	return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+	return (ns * ((host->bus_hz/2) / 1000000) + 999) / 1000;

Why don't you keep the notation by addign spaces around '/'? BTW, could use DIV_ROUND_UP() here.

WBR, Sergei

#3 lore raw

PATCH 1/3 mmc: atmel-mci: correct data timeout computation

Hello Sergei,

Quoted 13 lines · Sergei Shtylyov

Hello.

Quoted 8 lines · ludovic.desroches at atmel.com

From: Ludovic Desroches<[email protected]>

The HSMCI operates at a rate of up to Master Clock divided by two.

---
 drivers/mmc/host/atmel-mci.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Quoted 14 lines

drivers/mmc/host/atmel-mci.c err: · line 483

Quoted 10 lines
drivers/mmc/host/atmel-mci.c +1 -1
index e4449a5..e161452 100644
@@ -480,7 +480,7 @@ err:
 static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
 					unsigned int ns)
 {
-	return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+	return (ns * ((host->bus_hz/2) / 1000000) + 999) / 1000;

Why don't you keep the notation by addign spaces around '/'? BTW, could use DIV_ROUND_UP() here.

Thanks for your comments. BTW I have realized (when testing values return using DIV_ROUND_UP) that I may have another issue with this timeout calculation. I will send a new patch.

Regards

Ludovic

#4 lore raw

PATCH v2 1/3 mmc: atmel-mci: correct data timeout computation

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

The HSMCI operates at a rate of up to Master Clock divided by two. Moreover previous calculation can cause overflows and so wrong timeouts.

---
 drivers/mmc/host/atmel-mci.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
drivers/mmc/host/atmel-mci.c +8 -1
index e4449a5..3a57964 100644
@@ -480,7 +480,14 @@ err:
 static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
 					unsigned int ns)
 {
-	return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+	/*
+	 * It is easier here to use us instead of ns for the timeout,
+	 * it prevents from overflows during calculation.
+	 */
+	unsigned int us = DIV_ROUND_UP(ns, 1000);
+
+	/* Maximum clock frequency is host->bus_hz/2 */
+	return us * (DIV_ROUND_UP(host->bus_hz, 2000000));
 }
 
 static void atmci_set_timeout(struct atmel_mci *host,
Signature · 1 line
1.7.5.4
#5 lore raw

PATCH v2 1/3 mmc: atmel-mci: correct data timeout computation

On 03/28/2012 12:28 PM, ludovic.desroches at atmel.com :

Quoted 7 lines

From: Ludovic Desroches <[email protected]>

The HSMCI operates at a rate of up to Master Clock divided by two. Moreover previous calculation can cause overflows and so wrong timeouts.

Quoted 25 lines
Cc stable <[email protected]>
---
 drivers/mmc/host/atmel-mci.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
drivers/mmc/host/atmel-mci.c +8 -1
index e4449a5..3a57964 100644
@@ -480,7 +480,14 @@ err:
 static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
 					unsigned int ns)
 {
-	return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+	/*
+	 * It is easier here to use us instead of ns for the timeout,
+	 * it prevents from overflows during calculation.
+	 */
+	unsigned int us = DIV_ROUND_UP(ns, 1000);
+
+	/* Maximum clock frequency is host->bus_hz/2 */
+	return us * (DIV_ROUND_UP(host->bus_hz, 2000000));
 }
 
 static void atmci_set_timeout(struct atmel_mci *host,
Signature · 1 line
Nicolas Ferre
#6 lore raw

PATCH v2 1/3 mmc: atmel-mci: correct data timeout computation

Hi,

Quoted 10 lines · Nicolas Ferre

On 03/28/2012 12:28 PM, [email protected] :

Quoted 7 lines

From: Ludovic Desroches <[email protected]>

The HSMCI operates at a rate of up to Master Clock divided by two. Moreover previous calculation can cause overflows and so wrong timeouts.

Thanks, pushed to mmc-next for 3.4.

- Chris.

Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child
#7 lore raw

PATCH 2/3 mmc: atmel-mci: r/w proof capability only available since v2xx

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

---
 drivers/mmc/host/atmel-mci.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/mmc/host/atmel-mci.c +2 -0
index e161452..9dcb236 100644
@@ -2009,6 +2009,8 @@ static void __init atmci_get_cap(struct atmel_mci *host)
 	/* keep only major version number */
 	switch (version & 0xf00) {
 	case 0x100:
+		host->caps.has_pdc = 1;
+		break;
 	case 0x200:
 		host->caps.has_pdc = 1;
 		host->caps.has_rwproof = 1;
Signature · 1 line
1.7.5.4
#8 lore raw

PATCH 2/3 mmc: atmel-mci: r/w proof capability only available since v2xx

On 03/21/2012 04:41 PM, ludovic.desroches at atmel.com :

Quoted 3 lines

From: Ludovic Desroches <[email protected]>

Quoted 17 lines
---
 drivers/mmc/host/atmel-mci.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/mmc/host/atmel-mci.c +2 -0
index e161452..9dcb236 100644
@@ -2009,6 +2009,8 @@ static void __init atmci_get_cap(struct atmel_mci *host)
 	/* keep only major version number */
 	switch (version & 0xf00) {
 	case 0x100:
+		host->caps.has_pdc = 1;
+		break;
 	case 0x200:
 		host->caps.has_pdc = 1;
 		host->caps.has_rwproof = 1;
Signature · 1 line
Nicolas Ferre
#10 lore raw

PATCH 3/3 mmc: atmel-mci: add support for odd clock dividers

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Add an odd clock divider capability available from v5xx. It also involves changing the clock divider calculation.

---
 drivers/mmc/host/atmel-mci-regs.h |    1 +
 drivers/mmc/host/atmel-mci.c      |   48 ++++++++++++++++++++++--------------
 2 files changed, 30 insertions(+), 19 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +1 -0
index 000b3ad..787aba1 100644
@@ -31,6 +31,7 @@
 # define ATMCI_MR_PDCFBYTE		(  1 << 13)	/* Force Byte Transfer */
 # define ATMCI_MR_PDCPADV		(  1 << 14)	/* Padding Value */
 # define ATMCI_MR_PDCMODE		(  1 << 15)	/* PDC-oriented Mode */
+# define ATMCI_MR_CLKODD(x)		((x) << 16)	/* LSB of Clock Divider */
 #define ATMCI_DTOR			0x0008	/* Data Timeout */
 # define ATMCI_DTOCYC(x)		((x) <<  0)	/* Data Timeout Cycles */
 # define ATMCI_DTOMUL(x)		((x) <<  4)	/* Data Timeout Multiplier */
drivers/mmc/host/atmel-mci.c +29 -19

88 lines not on this page · raw message

Signature · 1 line
1.7.5.4
#11 lore raw

PATCH 3/3 mmc: atmel-mci: add support for odd clock dividers

On 03/21/2012 04:41 PM, ludovic.desroches at atmel.com :

Quoted 4 lines

From: Ludovic Desroches <[email protected]>

Add an odd clock divider capability available from v5xx. It also involves changing the clock divider calculation.

Also tell here that you have changed the way that the switch/case directive has been implemented.

Quoted 1 line

Otherwise:

Quoted 112 lines
---
 drivers/mmc/host/atmel-mci-regs.h |    1 +
 drivers/mmc/host/atmel-mci.c      |   48 ++++++++++++++++++++++--------------
 2 files changed, 30 insertions(+), 19 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +1 -0
index 000b3ad..787aba1 100644
@@ -31,6 +31,7 @@
 # define ATMCI_MR_PDCFBYTE		(  1 << 13)	/* Force Byte Transfer */
 # define ATMCI_MR_PDCPADV		(  1 << 14)	/* Padding Value */
 # define ATMCI_MR_PDCMODE		(  1 << 15)	/* PDC-oriented Mode */
+# define ATMCI_MR_CLKODD(x)		((x) << 16)	/* LSB of Clock Divider */
 #define ATMCI_DTOR			0x0008	/* Data Timeout */
 # define ATMCI_DTOCYC(x)		((x) <<  0)	/* Data Timeout Cycles */
 # define ATMCI_DTOMUL(x)		((x) <<  4)	/* Data Timeout Multiplier */
drivers/mmc/host/atmel-mci.c +29 -19
index 9dcb236..75e28c0 100644
@@ -76,6 +76,7 @@ struct atmel_mci_caps {
 	bool    has_cstor_reg;
 	bool    has_highspeed;
 	bool    has_rwproof;
+	bool	has_odd_clk_div;
 };
 
 struct atmel_mci_dma {
@@ -1124,16 +1125,27 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 
 		/* Calculate clock divider */
-		clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
-		if (clkdiv > 255) {
-			dev_warn(&mmc->class_dev,
-				"clock %u too slow; using %lu\n",
-				clock_min, host->bus_hz / (2 * 256));
-			clkdiv = 255;
+		if (host->caps.has_odd_clk_div) {
+			clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
+			if (clkdiv > 511) {
+				dev_warn(&mmc->class_dev,
+				         "clock %u too slow; using %lu\n",
+				         clock_min, host->bus_hz / (511 + 2));
+				clkdiv = 511;
+			}
+			host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1)
+			                 | ATMCI_MR_CLKODD(clkdiv & 1);
+		} else {
+			clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
+			if (clkdiv > 255) {
+				dev_warn(&mmc->class_dev,
+				         "clock %u too slow; using %lu\n",
+				         clock_min, host->bus_hz / (2 * 256));
+				clkdiv = 255;
+			}
+			host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
 		}
 
-		host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
-
 		/*
 		 * WRPROOF and RDPROOF prevent overruns/underruns by
 		 * stopping the clock when the FIFO is full/empty.
@@ -2000,37 +2012,35 @@ static void __init atmci_get_cap(struct atmel_mci *host)
 			"version: 0x%x\n", version);
 
 	host->caps.has_dma = 0;
-	host->caps.has_pdc = 0;
+	host->caps.has_pdc = 1;
 	host->caps.has_cfg_reg = 0;
 	host->caps.has_cstor_reg = 0;
 	host->caps.has_highspeed = 0;
 	host->caps.has_rwproof = 0;
+	host->caps.has_odd_clk_div = 0;
 
 	/* keep only major version number */
 	switch (version & 0xf00) {
-	case 0x100:
-		host->caps.has_pdc = 1;
-		break;
-	case 0x200:
-		host->caps.has_pdc = 1;
-		host->caps.has_rwproof = 1;
-		break;
-	case 0x300:
-	case 0x400:
 	case 0x500:
+		host->caps.has_odd_clk_div = 1;
+	case 0x400:
+	case 0x300:
 #ifdef CONFIG_AT_HDMAC
 		host->caps.has_dma = 1;
 #else
-		host->caps.has_dma = 0;
 		dev_info(&host->pdev->dev,
 			"has dma capability but dma engine is not selected, then use pio\n");
 #endif
+		host->caps.has_pdc = 0;
 		host->caps.has_cfg_reg = 1;
 		host->caps.has_cstor_reg = 1;
 		host->caps.has_highspeed = 1;
+	case 0x200:
 		host->caps.has_rwproof = 1;
+	case 0x100:
 		break;
 	default:
+		host->caps.has_pdc = 0;
 		dev_warn(&host->pdev->dev,
 				"Unmanaged mci version, set minimum capabilities\n");
 		break;
Signature · 1 line
Nicolas Ferre
#12 lore raw

PATCH 3/3 mmc: atmel-mci: add support for odd clock dividers

Hi,

Quoted 6 lines · Nicolas Ferre

On 03/21/2012 04:41 PM, [email protected] :

Quoted 4 lines

From: Ludovic Desroches <[email protected]>

Add an odd clock divider capability available from v5xx. It also involves changing the clock divider calculation.

Quoted 7 lines

Also tell here that you have changed the way that the switch/case directive has been implemented.

Quoted 1 line

Otherwise:

Thanks, pushed to mmc-next for 3.4 with a rewording:

Add an odd clock divider capability available from v5xx. It also involves changing the clock divider calculation, and changing the switch-case statement to use top-down fallthrough.

- Chris.

Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child
#13 lore raw

PATCH 3/3 mmc: atmel-mci: add support for odd clock dividers

Hi Chris,

Quoted 17 lines · Chris Ball

Hi,

Quoted 6 lines · Nicolas Ferre

On 03/21/2012 04:41 PM, ludovic.desroches at atmel.com :

Quoted 4 lines

From: Ludovic Desroches <[email protected]>

Add an odd clock divider capability available from v5xx. It also involves changing the clock divider calculation.

Quoted 7 lines

Also tell here that you have changed the way that the switch/case directive has been implemented.

Quoted 1 line

Otherwise:

Quoted 10 lines

Thanks, pushed to mmc-next for 3.4 with a rewording:

Add an odd clock divider capability available from v5xx. It also involves changing the clock divider calculation, and changing the switch-case statement to use top-down fallthrough.

- Chris.

Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child

Thanks for rewording the commit message.

Regards

Ludovic