* [PATCH 1/4] powerpc/85xx: Add support for 85xx cpu type detection
@ 2013-07-08 2:12 ` Haijun Zhang
0 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: cbouatmailru, cjb, scottwood, AFLEMING, Haijun Zhang, Zhao Chenhui
Add this file to help detect cpu type in runtime.
These macros and inline routines will be more favorable for driver
to apply errata and workaround to specified cpu type.
Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
---
arch/powerpc/include/asm/mpc85xx.h | 96 ++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 arch/powerpc/include/asm/mpc85xx.h
diff --git a/arch/powerpc/include/asm/mpc85xx.h b/arch/powerpc/include/asm/mpc85xx.h
new file mode 100644
index 0000000..a49fead
--- /dev/null
+++ b/arch/powerpc/include/asm/mpc85xx.h
@@ -0,0 +1,96 @@
+/*
+ * MPC85xx cpu type detection
+ *
+ * Copyright 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __ASM_PPC_CPU_H
+#define __ASM_PPC_CPU_H
+
+#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */
+#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/
+#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/
+
+/* Some parts define SVR[0:23] as the SOC version */
+#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFFFFF) /* SOC Version fields */
+
+#define IS_SVR_REV(svr, maj, min) \
+ ((SVR_MAJ(svr) == (maj)) && (SVR_MIN(svr) == (min)))
+
+#define SVR_8533 0x803400
+#define SVR_8533_E 0x803C00
+#define SVR_8535 0x803701
+#define SVR_8535_E 0x803F01
+#define SVR_8536 0x803700
+#define SVR_8536_E 0x803F00
+#define SVR_8540 0x803000
+#define SVR_8541 0x807200
+#define SVR_8541_E 0x807A00
+#define SVR_8543 0x803200
+#define SVR_8543_E 0x803A00
+#define SVR_8544 0x803401
+#define SVR_8544_E 0x803C01
+#define SVR_8545 0x803102
+#define SVR_8545_E 0x803902
+#define SVR_8547 0x803101
+#define SVR_8547_E 0x803901
+#define SVR_8548 0x803100
+#define SVR_8548_E 0x803900
+#define SVR_8555 0x807100
+#define SVR_8555_E 0x807900
+#define SVR_8560 0x807000
+#define SVR_8567 0x807501
+#define SVR_8567_E 0x807D01
+#define SVR_8568 0x807500
+#define SVR_8568_E 0x807D00
+#define SVR_8569 0x808000
+#define SVR_8569_E 0x808800
+#define SVR_8572 0x80E000
+#define SVR_8572_E 0x80E800
+#define SVR_P1010 0x80f900
+#define SVR_P1010_E 0x80F100
+#define SVR_P2041 0x821001
+#define SVR_P2041_E 0x821801
+#define SVR_P3041 0x821103
+#define SVR_P3041_E 0x821903
+#define SVR_P5010 0x822100
+#define SVR_P5010_E 0x822900
+#define SVR_P5020 0x822000
+#define SVR_P5020_E 0x822800
+#define SVR_P5040 0x820400
+#define SVR_P5040_E 0x820B00
+#define SVR_T4240 0x824800
+#define SVR_B4860 0x868800
+
+
+static inline int fsl_svr_is(u32 svr)
+{
+ u32 id = SVR_SOC_VER(mfspr(SPRN_SVR));
+
+ return (id == svr);
+}
+
+/* Check the SOC design version of this board */
+static inline int fsl_svr_rev_is(u8 maj, u8 min)
+{
+ u32 rev = SVR_REV(mfspr(SPRN_SVR));
+ u32 cmp = (maj << 4) | min;
+
+ return (rev == cmp);
+}
+
+/* Return true if current SOC revision is prior to (maj, min) */
+static inline int fsl_svr_older_than(u8 maj, u8 min)
+{
+ u32 rev = SVR_REV(mfspr(SPRN_SVR));
+ u32 cmp = (maj << 4) | min;
+
+ return (rev < cmp);
+}
+
+#endif
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 1/4] powerpc/85xx: Add support for 85xx cpu type detection
@ 2013-07-08 2:12 ` Haijun Zhang
0 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: Zhao Chenhui, AFLEMING, cbouatmailru, scottwood, cjb, Haijun Zhang
Add this file to help detect cpu type in runtime.
These macros and inline routines will be more favorable for driver
to apply errata and workaround to specified cpu type.
Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
---
arch/powerpc/include/asm/mpc85xx.h | 96 ++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 arch/powerpc/include/asm/mpc85xx.h
diff --git a/arch/powerpc/include/asm/mpc85xx.h b/arch/powerpc/include/asm/mpc85xx.h
new file mode 100644
index 0000000..a49fead
--- /dev/null
+++ b/arch/powerpc/include/asm/mpc85xx.h
@@ -0,0 +1,96 @@
+/*
+ * MPC85xx cpu type detection
+ *
+ * Copyright 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __ASM_PPC_CPU_H
+#define __ASM_PPC_CPU_H
+
+#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */
+#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/
+#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/
+
+/* Some parts define SVR[0:23] as the SOC version */
+#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFFFFF) /* SOC Version fields */
+
+#define IS_SVR_REV(svr, maj, min) \
+ ((SVR_MAJ(svr) == (maj)) && (SVR_MIN(svr) == (min)))
+
+#define SVR_8533 0x803400
+#define SVR_8533_E 0x803C00
+#define SVR_8535 0x803701
+#define SVR_8535_E 0x803F01
+#define SVR_8536 0x803700
+#define SVR_8536_E 0x803F00
+#define SVR_8540 0x803000
+#define SVR_8541 0x807200
+#define SVR_8541_E 0x807A00
+#define SVR_8543 0x803200
+#define SVR_8543_E 0x803A00
+#define SVR_8544 0x803401
+#define SVR_8544_E 0x803C01
+#define SVR_8545 0x803102
+#define SVR_8545_E 0x803902
+#define SVR_8547 0x803101
+#define SVR_8547_E 0x803901
+#define SVR_8548 0x803100
+#define SVR_8548_E 0x803900
+#define SVR_8555 0x807100
+#define SVR_8555_E 0x807900
+#define SVR_8560 0x807000
+#define SVR_8567 0x807501
+#define SVR_8567_E 0x807D01
+#define SVR_8568 0x807500
+#define SVR_8568_E 0x807D00
+#define SVR_8569 0x808000
+#define SVR_8569_E 0x808800
+#define SVR_8572 0x80E000
+#define SVR_8572_E 0x80E800
+#define SVR_P1010 0x80f900
+#define SVR_P1010_E 0x80F100
+#define SVR_P2041 0x821001
+#define SVR_P2041_E 0x821801
+#define SVR_P3041 0x821103
+#define SVR_P3041_E 0x821903
+#define SVR_P5010 0x822100
+#define SVR_P5010_E 0x822900
+#define SVR_P5020 0x822000
+#define SVR_P5020_E 0x822800
+#define SVR_P5040 0x820400
+#define SVR_P5040_E 0x820B00
+#define SVR_T4240 0x824800
+#define SVR_B4860 0x868800
+
+
+static inline int fsl_svr_is(u32 svr)
+{
+ u32 id = SVR_SOC_VER(mfspr(SPRN_SVR));
+
+ return (id == svr);
+}
+
+/* Check the SOC design version of this board */
+static inline int fsl_svr_rev_is(u8 maj, u8 min)
+{
+ u32 rev = SVR_REV(mfspr(SPRN_SVR));
+ u32 cmp = (maj << 4) | min;
+
+ return (rev == cmp);
+}
+
+/* Return true if current SOC revision is prior to (maj, min) */
+static inline int fsl_svr_older_than(u8 maj, u8 min)
+{
+ u32 rev = SVR_REV(mfspr(SPRN_SVR));
+ u32 cmp = (maj << 4) | min;
+
+ return (rev < cmp);
+}
+
+#endif
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] mmc: esdhc: workaround for dma err in the last system transaction
2013-07-08 2:12 ` Haijun Zhang
@ 2013-07-08 2:12 ` Haijun Zhang
-1 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: cbouatmailru, cjb, scottwood, AFLEMING, Haijun Zhang, Haijun Zhang
A-004388: eSDHC DMA might not stop if error occurs on system transaction
eSDHC DMA(SDMA/ADMA) might not stop if an error occurs in the last system
transaction. It may continue initiating additional transactions until
software reset for data/all is issued during error recovery. There is not
any data corruption to the SD data. The IRQSTAT[DMAE] is set when the
erratum occurs.
The only conditions under which issues occur are the following:
1. SDMA - For SD Write , the error occurs in the last system transaction.
No issue for SD read
2. ADMA
a. Block count is enabled: For SD write, the error occurs in the last system
transaction. There is no issue for SD read when block count is enabled.
b. Block count is disabled: Block count is designated by the ADMA descriptor
table, and the error occurs in the last system transaction when ADMA is
executing last descriptor line of table.
eSDHC may initiate additional system transactions. There is no data integrity
issue for case 1 and 2a described below. For case 2b, system data might be
corrupted.
Workaround: Set eSDHC_SYSCTL[RSTD] when IRQSTAT[DMAE] is set. For cases 2a and
2b above, add an extra descriptor line with zero data next to the last
descriptor line.
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
drivers/mmc/host/sdhci-of-esdhc.c | 113 +++++++++++++++++++++++++++++++++++---
1 file changed, 104 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 15039e2..b22cab0 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -21,6 +21,7 @@
#include <linux/mmc/host.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+#include <asm/mpc85xx.h>
#define VENDOR_V_22 0x12
#define VENDOR_V_23 0x13
@@ -142,6 +143,26 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
sdhci_be32bs_writeb(host, val, reg);
}
+static void esdhc_reset(struct sdhci_host *host, u8 mask)
+{
+ u32 ier;
+ u32 uninitialized_var(isav);
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ isav = esdhc_readl(host, SDHCI_INT_ENABLE);
+
+ esdhc_writeb(host, mask, SDHCI_SOFTWARE_RESET);
+ mdelay(100);
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
+ ier = esdhc_readl(host, SDHCI_INT_ENABLE);
+ ier &= ~SDHCI_INT_ALL_MASK;
+ ier |= isav;
+ esdhc_writel(host, ier, SDHCI_INT_ENABLE);
+ esdhc_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+ }
+}
+
/*
* For Abort or Suspend after Stop at Block Gap, ignore the ADMA
* error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC])
@@ -162,19 +183,93 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
applicable = (intmask & SDHCI_INT_DATA_END) &&
(intmask & SDHCI_INT_BLK_GAP) &&
(tmp == VENDOR_V_23);
- if (!applicable)
+ if (applicable) {
+
+ esdhc_reset(host, SDHCI_RESET_DATA);
+ host->data->error = 0;
+ dmastart = sg_dma_address(host->data->sg);
+ dmanow = dmastart + host->data->bytes_xfered;
+ /*
+ * Force update to the next DMA block boundary.
+ */
+ dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
+ SDHCI_DEFAULT_BOUNDARY_SIZE;
+ host->data->bytes_xfered = dmanow - dmastart;
+ sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+
return;
+ }
- host->data->error = 0;
- dmastart = sg_dma_address(host->data->sg);
- dmanow = dmastart + host->data->bytes_xfered;
/*
- * Force update to the next DMA block boundary.
+ * Check for A-004388: eSDHC DMA might not stop if error
+ * occurs on system transaction
+ * Impact list:
+ * T4240-R1.0 B4860-R1.0 P1010-R1.0
*/
- dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
- SDHCI_DEFAULT_BOUNDARY_SIZE;
- host->data->bytes_xfered = dmanow - dmastart;
- sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+ if (!((fsl_svr_is(SVR_T4240) && fsl_svr_rev_is(1, 0)) ||
+ (fsl_svr_is(SVR_B4860) && fsl_svr_rev_is(1, 0)) ||
+ (fsl_svr_is(SVR_P1010) && fsl_svr_rev_is(1, 0))))
+ return;
+
+
+ esdhc_reset(host, SDHCI_RESET_DATA);
+
+ if (host->flags & SDHCI_USE_ADMA) {
+ u32 mod, i, offset;
+ u8 *desc;
+ dma_addr_t addr;
+ struct scatterlist *sg;
+
+ mod = esdhc_readl(host, SDHCI_TRANSFER_MODE);
+ if (mod & SDHCI_TRNS_BLK_CNT_EN) {
+ /*
+ * In case read transfer there is no data
+ * was corrupted
+ */
+ if (host->data->flags & MMC_DATA_READ)
+ host->data->error = 0;
+
+ return;
+ }
+
+
+ BUG_ON(!host->data);
+ desc = host->adma_desc;
+ for_each_sg(host->data->sg, sg, host->sg_count, i) {
+ addr = sg_dma_address(sg);
+ offset = (4 - (addr & 0x3)) & 0x3;
+ if (offset)
+ desc += 8;
+ desc += 8;
+ }
+
+ /*
+ * Add an extra zero descriptor next to the
+ * terminating descriptor.
+ */
+ desc += 8;
+ WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
+
+ if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
+ desc -= 8;
+ desc[0] |= 0x2; /* end */
+ } else {
+ __le32 *dataddr = (__le32 __force *)(desc + 4);
+ __le16 *cmdlen = (__le16 __force *)desc;
+
+ cmdlen[0] = cpu_to_le16(0x3);
+ cmdlen[1] = cpu_to_le16(0);
+
+ dataddr[0] = cpu_to_le32(0);
+ }
+
+ }
+
+ if ((host->flags & SDHCI_USE_SDMA) &&
+ (host->data->flags & MMC_DATA_READ))
+ host->data->error = 0;
+
+ return;
}
static int esdhc_of_enable_dma(struct sdhci_host *host)
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] mmc: esdhc: workaround for dma err in the last system transaction
@ 2013-07-08 2:12 ` Haijun Zhang
0 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: scottwood, cjb, AFLEMING, Haijun Zhang, cbouatmailru
A-004388: eSDHC DMA might not stop if error occurs on system transaction
eSDHC DMA(SDMA/ADMA) might not stop if an error occurs in the last system
transaction. It may continue initiating additional transactions until
software reset for data/all is issued during error recovery. There is not
any data corruption to the SD data. The IRQSTAT[DMAE] is set when the
erratum occurs.
The only conditions under which issues occur are the following:
1. SDMA - For SD Write , the error occurs in the last system transaction.
No issue for SD read
2. ADMA
a. Block count is enabled: For SD write, the error occurs in the last system
transaction. There is no issue for SD read when block count is enabled.
b. Block count is disabled: Block count is designated by the ADMA descriptor
table, and the error occurs in the last system transaction when ADMA is
executing last descriptor line of table.
eSDHC may initiate additional system transactions. There is no data integrity
issue for case 1 and 2a described below. For case 2b, system data might be
corrupted.
Workaround: Set eSDHC_SYSCTL[RSTD] when IRQSTAT[DMAE] is set. For cases 2a and
2b above, add an extra descriptor line with zero data next to the last
descriptor line.
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
drivers/mmc/host/sdhci-of-esdhc.c | 113 +++++++++++++++++++++++++++++++++++---
1 file changed, 104 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 15039e2..b22cab0 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -21,6 +21,7 @@
#include <linux/mmc/host.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+#include <asm/mpc85xx.h>
#define VENDOR_V_22 0x12
#define VENDOR_V_23 0x13
@@ -142,6 +143,26 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
sdhci_be32bs_writeb(host, val, reg);
}
+static void esdhc_reset(struct sdhci_host *host, u8 mask)
+{
+ u32 ier;
+ u32 uninitialized_var(isav);
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ isav = esdhc_readl(host, SDHCI_INT_ENABLE);
+
+ esdhc_writeb(host, mask, SDHCI_SOFTWARE_RESET);
+ mdelay(100);
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
+ ier = esdhc_readl(host, SDHCI_INT_ENABLE);
+ ier &= ~SDHCI_INT_ALL_MASK;
+ ier |= isav;
+ esdhc_writel(host, ier, SDHCI_INT_ENABLE);
+ esdhc_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+ }
+}
+
/*
* For Abort or Suspend after Stop at Block Gap, ignore the ADMA
* error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC])
@@ -162,19 +183,93 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
applicable = (intmask & SDHCI_INT_DATA_END) &&
(intmask & SDHCI_INT_BLK_GAP) &&
(tmp == VENDOR_V_23);
- if (!applicable)
+ if (applicable) {
+
+ esdhc_reset(host, SDHCI_RESET_DATA);
+ host->data->error = 0;
+ dmastart = sg_dma_address(host->data->sg);
+ dmanow = dmastart + host->data->bytes_xfered;
+ /*
+ * Force update to the next DMA block boundary.
+ */
+ dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
+ SDHCI_DEFAULT_BOUNDARY_SIZE;
+ host->data->bytes_xfered = dmanow - dmastart;
+ sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+
return;
+ }
- host->data->error = 0;
- dmastart = sg_dma_address(host->data->sg);
- dmanow = dmastart + host->data->bytes_xfered;
/*
- * Force update to the next DMA block boundary.
+ * Check for A-004388: eSDHC DMA might not stop if error
+ * occurs on system transaction
+ * Impact list:
+ * T4240-R1.0 B4860-R1.0 P1010-R1.0
*/
- dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
- SDHCI_DEFAULT_BOUNDARY_SIZE;
- host->data->bytes_xfered = dmanow - dmastart;
- sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+ if (!((fsl_svr_is(SVR_T4240) && fsl_svr_rev_is(1, 0)) ||
+ (fsl_svr_is(SVR_B4860) && fsl_svr_rev_is(1, 0)) ||
+ (fsl_svr_is(SVR_P1010) && fsl_svr_rev_is(1, 0))))
+ return;
+
+
+ esdhc_reset(host, SDHCI_RESET_DATA);
+
+ if (host->flags & SDHCI_USE_ADMA) {
+ u32 mod, i, offset;
+ u8 *desc;
+ dma_addr_t addr;
+ struct scatterlist *sg;
+
+ mod = esdhc_readl(host, SDHCI_TRANSFER_MODE);
+ if (mod & SDHCI_TRNS_BLK_CNT_EN) {
+ /*
+ * In case read transfer there is no data
+ * was corrupted
+ */
+ if (host->data->flags & MMC_DATA_READ)
+ host->data->error = 0;
+
+ return;
+ }
+
+
+ BUG_ON(!host->data);
+ desc = host->adma_desc;
+ for_each_sg(host->data->sg, sg, host->sg_count, i) {
+ addr = sg_dma_address(sg);
+ offset = (4 - (addr & 0x3)) & 0x3;
+ if (offset)
+ desc += 8;
+ desc += 8;
+ }
+
+ /*
+ * Add an extra zero descriptor next to the
+ * terminating descriptor.
+ */
+ desc += 8;
+ WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
+
+ if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
+ desc -= 8;
+ desc[0] |= 0x2; /* end */
+ } else {
+ __le32 *dataddr = (__le32 __force *)(desc + 4);
+ __le16 *cmdlen = (__le16 __force *)desc;
+
+ cmdlen[0] = cpu_to_le16(0x3);
+ cmdlen[1] = cpu_to_le16(0);
+
+ dataddr[0] = cpu_to_le32(0);
+ }
+
+ }
+
+ if ((host->flags & SDHCI_USE_SDMA) &&
+ (host->data->flags & MMC_DATA_READ))
+ host->data->error = 0;
+
+ return;
}
static int esdhc_of_enable_dma(struct sdhci_host *host)
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] mmc: esdhc: Add quirks to support T4240 board
2013-07-08 2:12 ` Haijun Zhang
@ 2013-07-08 2:12 ` Haijun Zhang
-1 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: cbouatmailru, cjb, scottwood, AFLEMING, Haijun Zhang, Haijun Zhang
On T4240 board controllers has an unusable ADMA engine, so use SDMA instead.
Also 3.0v is support on T4240 board even if the capacity detailed only 1.8v
support. Without this quirk SD card will declare voltage not support and
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
drivers/mmc/host/sdhci-pltfm.c | 5 +++++
drivers/mmc/host/sdhci.c | 3 +++
include/linux/mmc/sdhci.h | 2 ++
3 files changed, 10 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index e2065a4..02edb3d 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -92,6 +92,11 @@ void sdhci_get_of_property(struct platform_device *pdev)
if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+ if (of_device_is_compatible(np, "fsl,t4240-esdhc")) {
+ host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+ host->quirks2 |= SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30;
+ }
+
if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
of_device_is_compatible(np, "fsl,p1010-esdhc") ||
of_device_is_compatible(np, "fsl,t4240-esdhc") ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a78bd4f..de7fa81 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2797,6 +2797,9 @@ int sdhci_add_host(struct sdhci_host *host)
host->caps1 :
sdhci_readl(host, SDHCI_CAPABILITIES_1);
+ if (host->quirks2 & SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30)
+ caps[0] = caps[0] | SDHCI_CAN_VDD_300;
+
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_SDMA;
else if (!(caps[0] & SDHCI_CAN_DO_SDMA))
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index e3c6a74..dc608d7 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -98,6 +98,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4)
/* Controller has a non-standard host control register */
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
+/* The host support VS300 even if the capacity detailed not */
+#define SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30 (1<<6)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] mmc: esdhc: Add quirks to support T4240 board
@ 2013-07-08 2:12 ` Haijun Zhang
0 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: scottwood, cjb, AFLEMING, Haijun Zhang, cbouatmailru
On T4240 board controllers has an unusable ADMA engine, so use SDMA instead.
Also 3.0v is support on T4240 board even if the capacity detailed only 1.8v
support. Without this quirk SD card will declare voltage not support and
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
drivers/mmc/host/sdhci-pltfm.c | 5 +++++
drivers/mmc/host/sdhci.c | 3 +++
include/linux/mmc/sdhci.h | 2 ++
3 files changed, 10 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index e2065a4..02edb3d 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -92,6 +92,11 @@ void sdhci_get_of_property(struct platform_device *pdev)
if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+ if (of_device_is_compatible(np, "fsl,t4240-esdhc")) {
+ host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+ host->quirks2 |= SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30;
+ }
+
if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
of_device_is_compatible(np, "fsl,p1010-esdhc") ||
of_device_is_compatible(np, "fsl,t4240-esdhc") ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a78bd4f..de7fa81 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2797,6 +2797,9 @@ int sdhci_add_host(struct sdhci_host *host)
host->caps1 :
sdhci_readl(host, SDHCI_CAPABILITIES_1);
+ if (host->quirks2 & SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30)
+ caps[0] = caps[0] | SDHCI_CAN_VDD_300;
+
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_SDMA;
else if (!(caps[0] & SDHCI_CAN_DO_SDMA))
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index e3c6a74..dc608d7 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -98,6 +98,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4)
/* Controller has a non-standard host control register */
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
+/* The host support VS300 even if the capacity detailed not */
+#define SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30 (1<<6)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] mmc: eSDHC: Some eSDHC host need long time to generate command interrupt
2013-07-08 2:12 ` Haijun Zhang
@ 2013-07-08 2:12 ` Haijun Zhang
-1 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: cbouatmailru, cjb, scottwood, AFLEMING, Haijun Zhang, Haijun Zhang
Command complete interrupt not always generate within 10 * HZ. Sometimes
500 * HZ or more. So enlarge this detecting value to ensure the host had
sufficient time to generate command complete interrupt.
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
drivers/mmc/host/sdhci-of-esdhc.c | 3 +++
drivers/mmc/host/sdhci.c | 10 +++++++++-
include/linux/mmc/sdhci.h | 2 ++
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index b22cab0..b616b03 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -331,6 +331,9 @@ static void esdhc_of_platform_init(struct sdhci_host *host)
if (vvn > VENDOR_V_22)
host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+
+ if (fsl_svr_is(SVR_B4860) || fsl_svr_is(SVR_T4240))
+ host->quirks2 |= SDHCI_QUIRK2_LONG_TM_CMD_COMPLETE_IRQ;
}
static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index de7fa81..35015ba 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -986,6 +986,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
int flags;
u32 mask;
unsigned long timeout;
+ int timer = 10;
WARN_ON(host->cmd);
@@ -1014,7 +1015,14 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
mdelay(1);
}
- mod_timer(&host->timer, jiffies + 10 * HZ);
+ /*
+ * Some eSDHC controller need long time to generate command complete
+ * interrupt, 1000 * HZ will be enough.
+ */
+ if (host->quirks2 & SDHCI_QUIRK2_LONG_TM_CMD_COMPLETE_IRQ)
+ timer = 1000;
+
+ mod_timer(&host->timer, jiffies + timer * HZ);
host->cmd = cmd;
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index dc608d7..68e7dd1 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -100,6 +100,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
/* The host support VS300 even if the capacity detailed not */
#define SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30 (1<<6)
+/* Some controller need long time to generate command complete interrupt */
+#define SDHCI_QUIRK2_LONG_TM_CMD_COMPLETE_IRQ (1<<7)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] mmc: eSDHC: Some eSDHC host need long time to generate command interrupt
@ 2013-07-08 2:12 ` Haijun Zhang
0 siblings, 0 replies; 10+ messages in thread
From: Haijun Zhang @ 2013-07-08 2:12 UTC (permalink / raw)
To: linux-mmc, linuxppc-dev
Cc: scottwood, cjb, AFLEMING, Haijun Zhang, cbouatmailru
Command complete interrupt not always generate within 10 * HZ. Sometimes
500 * HZ or more. So enlarge this detecting value to ensure the host had
sufficient time to generate command complete interrupt.
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
drivers/mmc/host/sdhci-of-esdhc.c | 3 +++
drivers/mmc/host/sdhci.c | 10 +++++++++-
include/linux/mmc/sdhci.h | 2 ++
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index b22cab0..b616b03 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -331,6 +331,9 @@ static void esdhc_of_platform_init(struct sdhci_host *host)
if (vvn > VENDOR_V_22)
host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+
+ if (fsl_svr_is(SVR_B4860) || fsl_svr_is(SVR_T4240))
+ host->quirks2 |= SDHCI_QUIRK2_LONG_TM_CMD_COMPLETE_IRQ;
}
static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index de7fa81..35015ba 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -986,6 +986,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
int flags;
u32 mask;
unsigned long timeout;
+ int timer = 10;
WARN_ON(host->cmd);
@@ -1014,7 +1015,14 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
mdelay(1);
}
- mod_timer(&host->timer, jiffies + 10 * HZ);
+ /*
+ * Some eSDHC controller need long time to generate command complete
+ * interrupt, 1000 * HZ will be enough.
+ */
+ if (host->quirks2 & SDHCI_QUIRK2_LONG_TM_CMD_COMPLETE_IRQ)
+ timer = 1000;
+
+ mod_timer(&host->timer, jiffies + timer * HZ);
host->cmd = cmd;
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index dc608d7..68e7dd1 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -100,6 +100,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
/* The host support VS300 even if the capacity detailed not */
#define SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS30 (1<<6)
+/* Some controller need long time to generate command complete interrupt */
+#define SDHCI_QUIRK2_LONG_TM_CMD_COMPLETE_IRQ (1<<7)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
1.8.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] powerpc/85xx: Add support for 85xx cpu type detection
2013-07-08 2:12 ` Haijun Zhang
@ 2013-07-08 23:43 ` Scott Wood
-1 siblings, 0 replies; 10+ messages in thread
From: Scott Wood @ 2013-07-08 23:43 UTC (permalink / raw)
Cc: linux-mmc, linuxppc-dev, cbouatmailru, cjb, AFLEMING,
Haijun Zhang, Zhao Chenhui
On 07/07/2013 09:12:22 PM, Haijun Zhang wrote:
> Add this file to help detect cpu type in runtime.
> These macros and inline routines will be more favorable for driver
> to apply errata and workaround to specified cpu type.
>
> Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
> arch/powerpc/include/asm/mpc85xx.h | 96
> ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 96 insertions(+)
> create mode 100644 arch/powerpc/include/asm/mpc85xx.h
What changed since the last time this was posted? I don't see any of
the feedback addressed that I gave here:
http://patchwork.ozlabs.org/patch/144880/
-Scott
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] powerpc/85xx: Add support for 85xx cpu type detection
@ 2013-07-08 23:43 ` Scott Wood
0 siblings, 0 replies; 10+ messages in thread
From: Scott Wood @ 2013-07-08 23:43 UTC (permalink / raw)
To: Haijun Zhang
Cc: Zhao Chenhui, linux-mmc, AFLEMING, cbouatmailru, cjb,
linuxppc-dev, Haijun Zhang
On 07/07/2013 09:12:22 PM, Haijun Zhang wrote:
> Add this file to help detect cpu type in runtime.
> These macros and inline routines will be more favorable for driver
> to apply errata and workaround to specified cpu type.
>=20
> Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
> arch/powerpc/include/asm/mpc85xx.h | 96 =20
> ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 96 insertions(+)
> create mode 100644 arch/powerpc/include/asm/mpc85xx.h
What changed since the last time this was posted? I don't see any of =20
the feedback addressed that I gave here:
http://patchwork.ozlabs.org/patch/144880/
-Scott=
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-07-08 23:43 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-08 2:12 [PATCH 1/4] powerpc/85xx: Add support for 85xx cpu type detection Haijun Zhang
2013-07-08 2:12 ` Haijun Zhang
2013-07-08 2:12 ` [PATCH 2/4] mmc: esdhc: workaround for dma err in the last system transaction Haijun Zhang
2013-07-08 2:12 ` Haijun Zhang
2013-07-08 2:12 ` [PATCH 3/4] mmc: esdhc: Add quirks to support T4240 board Haijun Zhang
2013-07-08 2:12 ` Haijun Zhang
2013-07-08 2:12 ` [PATCH 4/4] mmc: eSDHC: Some eSDHC host need long time to generate command interrupt Haijun Zhang
2013-07-08 2:12 ` Haijun Zhang
2013-07-08 23:43 ` [PATCH 1/4] powerpc/85xx: Add support for 85xx cpu type detection Scott Wood
2013-07-08 23:43 ` Scott Wood
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.