SDHCI support for Samsung SoC
Subsystems (3)
Ben Dooks
maintainercover SDHCI support for Samsung SoC
The following patch set gets working SDHCI on the
Samsung SoC series.
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Ben Dooks
maintainerPATCH 1/7 SDHCI: Add timeout hooks
Some controllers do not provide clock information in their capabilities (in the Samsung case, it is because there are multiple clock sources available to the controller). Add hooks to allow the system to supply clock information.
drivers/mmc/host/sdhci.c +11 -5
@@ -1604,17 +1604,23 @@ int sdhci_add_host(struct sdhci_host *hommc_dev (host->mmc)->dma_mask = &host->dma_mask; } - host->max_clk = - (caps &SDHCI_CLOCK_BASE_MASK ) >>SDHCI_CLOCK_BASE_SHIFT ; +if (host->ops->get_max_clock) + host->max_clk = host->ops->get_max_clock (host); +else { + host->max_clk = (caps &SDHCI_CLOCK_BASE_MASK ) >>SDHCI_CLOCK_BASE_SHIFT ; + host->max_clk *=1000000 ; + }if (host->max_clk ==0 ) {printk (KERN_ERR "%s: Hardware doesn't specify base clock " "frequency.\n" ,mmc_hostname (mmc));return -ENODEV ; } - host->max_clk *=1000000 ; - host->timeout_clk = - (caps &SDHCI_TIMEOUT_CLK_MASK ) >>SDHCI_TIMEOUT_CLK_SHIFT ; +if (host->ops->get_timeout_clock) + host->timeout_clk = host->ops->get_timeout_clock (host); +else + host->timeout_clk = + (caps &SDHCI_TIMEOUT_CLK_MASK ) >>SDHCI_TIMEOUT_CLK_SHIFT ;if (host->timeout_clk ==0 ) {printk (KERN_ERR "%s: Hardware doesn't specify timeout clock " "frequency.\n" ,mmc_hostname (mmc));
drivers/mmc/host/sdhci.h +2 -0
@@ -267,6 +267,8 @@ struct sdhci_host {struct sdhci_ops {int (*enable_dma)(struct sdhci_host *host); +unsigned int (*get_max_clock)(struct sdhci_host *host); +unsigned int (*get_timeout_clock)(struct sdhci_host *host); };
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 1/7] SDHCI: Add timeout hooks
Quoted 7 lines · On Mon, 03 Nov 2008 20:09:45 +0000 Ben Dooks <[email protected]> wrote:
Some controllers do not provide clock information in their capabilities (in the Samsung case, it is because there are multiple clock sources available to the controller). Add hooks to allow the system to supply clock information.
Signed-off-by Ben Dooks <[email protected]>
Could we at least initally try to strictly adhere to the SDHCI spec and only use the callback if the controller reports 0 for the freqs?
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerPATCH 2/7 SDHCI: Print ADMA status and pointer on debug
In reply to Ben DooksIf using ADMA, then we should print the ADMA error and current pointer in sdhci_dumpregs() when any debug is requested.
drivers/mmc/host/sdhci.c +5 -0
@@ -73,6 +73,11 @@ static void sdhci_dumpregs(struct sdhci_readl (host->ioaddr +SDHCI_CAPABILITIES ), readl(host->ioaddr + SDHCI_MAX_CURRENT)); +if (host->flags &SDHCI_USE_ADMA ) + printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", +readl (host->ioaddr +SDHCI_ADMA_ERROR ), +readl (host->ioaddr +SDHCI_ADMA_ADDRESS )); + printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); }
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 2/7] SDHCI: Print ADMA status and pointer on debug
Quoted 6 lines · On Mon, 03 Nov 2008 20:09:46 +0000 Ben Dooks <[email protected]> wrote:
If using ADMA, then we should print the ADMA error and current pointer in
sdhci_dumpregs()when any debug is requested.Signed-off-by Ben Dooks <[email protected]>
Looks ok. I think that dump routine could use some more TLC to be really useful.
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerPATCH 3/7 SDHCI: Add set_ios hook
In reply to Ben DooksAdd a set_ios hook which is called when the SDHCI driver is called to change parameters such as clock or card width.
drivers/mmc/host/sdhci.c +3 -0
@@ -1038,6 +1038,9 @@ static void sdhci_set_ios(struct mmc_hossdhci_init (host); } +if (host->ops->set_ios) + host->ops->set_ios (host, ios); +sdhci_set_clock (host, ios->clock);if (ios->power_mode ==MMC_POWER_OFF )
drivers/mmc/host/sdhci.h +3 -0
@@ -269,6 +269,9 @@ struct sdhci_ops {int (*enable_dma)(struct sdhci_host *host);unsigned int (*get_max_clock)(struct sdhci_host *host);unsigned int (*get_timeout_clock)(struct sdhci_host *host); + +void (*set_ios)(struct sdhci_host *host, +struct mmc_ios *ios); };
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 3/7] SDHCI: Add set_ios hook
Quoted 6 lines · On Mon, 03 Nov 2008 20:09:47 +0000 Ben Dooks <[email protected]> wrote:
Add a
set_ioshook which is called when the SDHCI driver is called to change parameters such as clock or card width.Signed-off-by Ben Dooks <[email protected]>
Hmm... this is very general and very much undefined. I think we need to have some kind of formal API here or I might end up breaking S3C support when I hack away at the driver.
Preferable, I'd like to see a more fine grained set of callbacks.
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerPATCH 4/7 SDHCI: Add quirk for controller with no end-of-busy IRQ
In reply to Ben DooksThe Samsung SDHCI controller block seems to fail to generate an INT_DATA_END after the transfer has completed and the bus busy state finished.
Changes in e809517f6fa5803a5a1cd56026f0e2190fc13d5c to use the new busy method are the cause of the behaviour change.
drivers/mmc/host/sdhci.c +14 -1
@@ -1291,11 +1291,24 @@ static void sdhci_cmd_irq(struct sdhci_h* controllers. */ if (host->cmd->flags &MMC_RSP_BUSY ) { +u32 present; +if (host->cmd->data)DBG ("Cannot wait for busy signal when also " "doing a data transfer" ); -else +else if (!(host->quirks &SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY ))return ; + +/* The Samsung SDHCI does not seem to provide an INT_DATA_END +* when the system goes non-busy, so check the state of the +* transfer by reading SDHCI_PRESENT_STATE to see if the +* controller is ready +*/ + + present =readl (host->ioaddr +SDHCI_PRESENT_STATE ); +DBG ("busy? present %08x, intstat %08x\n" , present, intmask); + +/* fall through and take the SDHCI_INT_RESPONSE */ }if (intmask &SDHCI_INT_RESPONSE )
drivers/mmc/host/sdhci.h +3 -0
@@ -57,6 +57,7 @@#define SDHCI_DATA_AVAILABLE 0x00000800#define SDHCI_CARD_PRESENT 0x00010000#define SDHCI_WRITE_PROTECT 0x00080000 +#define SDHCI_DATA_BIT (x) (1 << ((x) + 20))#define SDHCI_HOST_CONTROL 0x28#define SDHCI_CTRL_LED 0x01
@@ -210,6 +211,8 @@ struct sdhci_host {#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)/* Controller supports high speed but doesn't have the caps bit set */ #define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) +/* Controller does not provide transfer-complete interrupt when not busy */ +#define SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY (1<<15)int irq;/* Device IRQ */ void __iomem * ioaddr;/* Mapped address */
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 4/7] SDHCI: Add quirk for controller with no end-of-busy IRQ
Quoted 15 lines · On Mon, 03 Nov 2008 20:09:48 +0000 Ben Dooks <[email protected]> wrote:
The Samsung SDHCI controller block seems to fail to generate an
INT_DATA_ENDafter the transfer has completed and the bus busy state finished.Changes in
e809517f6fa5803a5a1cd56026f0e2190fc13d5cto use the new busy method are the cause of the behaviour change.Signed-off-by Ben Dooks <[email protected]>Index:
linux.git/drivers/mmc/host/sdhci.c
===================================================================drivers/mmc/host/sdhci.c +0
-0@@ -1291,11 +1291,24 @@ static void sdhci_cmd_irq(struct sdhci_h* controllers.
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1300
Quoted 10 lines
drivers/mmc/host/sdhci.c +3
-1*/ if (host->cmd->flags &MMC_RSP_BUSY ) { +u32 present; +if (host->cmd->data)DBG ("Cannot wait for busy signal when also " "doing a data transfer" ); -else +else if (!(host->quirks &SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY ))return ;
Not the clearest naming I've ever seen. :)
How about NO_BUSY_IRQ?
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1306
Quoted 6 lines
drivers/mmc/host/sdhci.c +6
-0+ +/* The Samsung SDHCI does not seem to provide an INT_DATA_END +* when the system goes non-busy, so check the state of the +* transfer by reading SDHCI_PRESENT_STATE to see if the +* controller is ready +*/
There is already a note about this being a problem earlier up, so I don't think we need another.
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1310
Quoted 4 lines
drivers/mmc/host/sdhci.c +4
-0+ + present =readl (host->ioaddr +SDHCI_PRESENT_STATE ); +DBG ("busy? present %08x, intstat %08x\n" , present, intmask); +
And what does this add really? Controllers not being able to wait for the busy state to end is so common that we can just ignore the problem here.
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1311
Quoted 1 line
drivers/mmc/host/sdhci.c +1
-0+#define SDHCI_DATA_BIT (x) (1 << ((x) + 20))
This was not supposed to be included I suppose :)
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerRe: [patch 4/7] SDHCI: Add quirk for controller with no end-of-busy IRQ
Quoted 23 lines · Pierre Ossman
Quoted 20 lines · On Mon, 03 Nov 2008 20:09:48 +0000 Ben Dooks <[email protected]> wrote:
The Samsung SDHCI controller block seems to fail to generate an
INT_DATA_ENDafter the transfer has completed and the bus busy state finished.Changes in
e809517f6fa5803a5a1cd56026f0e2190fc13d5cto use the new busy method are the cause of the behaviour change.Signed-off-by Ben Dooks <[email protected]>Index:
linux.git/drivers/mmc/host/sdhci.c
===================================================================drivers/mmc/host/sdhci.c +2
-0@@ -1291,11 +1291,24 @@ static void sdhci_cmd_irq(struct sdhci_h* controllers. */ if (host->cmd->flags &MMC_RSP_BUSY ) { +u32 present; +if (host->cmd->data)
Quoted 8 lines
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1300
Quoted 5 lines
drivers/mmc/host/sdhci.c +1
-1DBG ("Cannot wait for busy signal when also " "doing a data transfer" ); - else + else if (!(host->quirks & SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY))return ;Not the clearest naming I've ever seen. :)
How aboutNO_BUSY_IRQ?
ok, will change.
Quoted 9 lines
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1306
Quoted 6 lines
drivers/mmc/host/sdhci.c +6
-0+ +/* The Samsung SDHCI does not seem to provide an INT_DATA_END +* when the system goes non-busy, so check the state of the +* transfer by reading SDHCI_PRESENT_STATE to see if the +* controller is ready +*/ There is already a note about this being a problem earlier up, so I don't think we need another.
right.
Quoted 9 lines
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1310
Quoted 4 lines
drivers/mmc/host/sdhci.c +4
-0+ + present =readl (host->ioaddr +SDHCI_PRESENT_STATE ); +DBG ("busy? present %08x, intstat %08x\n" , present, intmask); +And what does this add really? Controllers not being able to wait for the busy state to end is so common that we can just ignore the problem here.
that was debug.
Quoted 3 lines
drivers/mmc/host/sdhci.c static void sdhci_cmd_irq(struct sdhci_h · line 1311
Quoted 1 line
drivers/mmc/host/sdhci.c +1
-0+#define SDHCI_DATA_BIT (x) (1 << ((x) + 20))This was not supposed to be included I suppose :)
was with teh debug.
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Ben Dooks
maintainerPATCH 5/7 SDHCI: Samsung SDHCI (HSMMC) driver
In reply to Ben DooksAdd support for the 'HSMMC' block(s) in the Samsung SoC line. These are compatible with the SDHCI driver so add the necessary setup and driver binding for the platform devices.
drivers/mmc/host/Kconfig +12 -0
@@ -48,6 +48,18 @@ config MMC_SDHCI_PCI If unsure, say N. +config MMC_SDHCI_S3C + tristate "SDHCI support on Samsung S3C SoC" + depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX) + help + This selects the Secure Digital Host Controller Interface (SDHCI) + often referrered to as the HSMMC block in some of the Samsung S3C + range of SoC. + + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + config MMC_RICOH_MMC tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" depends on MMC_SDHCI_PCI
drivers/mmc/host/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_IMX) += imxmmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o +obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
drivers/mmc/host/sdhci-s3c.c new file +294 -0
294 lines not on this page · raw message
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 5/7] SDHCI: Samsung SDHCI (HSMMC) driver
Quoted 4 lines · On Mon, 03 Nov 2008 20:09:49 +0000 Ben Dooks <[email protected]> wrote:
drivers/mmc/host/sdhci-s3c.c new file +4
-0+static void sdhci_s3c_sel_sclk (struct sdhci_host *host) +{ +struct sdhci_s3c *ourhost =to_s3c (host); +
drivers/mmc/host/sdhci-s3c.c line 58
Quoted 10 lines
drivers/mmc/host/sdhci-s3c.c new file +10
-0+/* select sclk */ +u32 tmp =readl (host->ioaddr +0x80 ); + +if ((tmp & (3 <<4 )) == (2 <<4 )) +return ; + + tmp &= ~(3 <<4 ); + tmp |= (2 <<4 ); +writel (tmp, host->ioaddr +0x80 ); +}
No defines for this? This is not terribly readable.
drivers/mmc/host/sdhci-s3c.c line 110
Quoted 3 lines
drivers/mmc/host/sdhci-s3c.c new file +3
-0+if (pdata->cfg_card) + pdata->cfg_card (ourhost->pdev, host->ioaddr, + ios, host->mmc->card);
What's the deal here? Hosts shouldn't know more about the card than the MMC core tells them.
Since I have no hardware for this, could you take it upon you to handle support for these chips? I'd like a MAINTAINERS patch for that as well.
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerRe: [patch 5/7] SDHCI: Samsung SDHCI (HSMMC) driver
Quoted 19 lines · Pierre Ossman
Quoted 4 lines · On Mon, 03 Nov 2008 20:09:49 +0000 Ben Dooks <[email protected]> wrote:
drivers/mmc/host/sdhci-s3c.c new file +4
-0+static void sdhci_s3c_sel_sclk (struct sdhci_host *host) +{ +struct sdhci_s3c *ourhost =to_s3c (host); +drivers/mmc/host/sdhci-s3c.c line 58
Quoted 10 lines
drivers/mmc/host/sdhci-s3c.c new file +10
-0+/* select sclk */ +u32 tmp =readl (host->ioaddr +0x80 ); + +if ((tmp & (3 <<4 )) == (2 <<4 )) +return ; + + tmp &= ~(3 <<4 ); + tmp |= (2 <<4 ); +writel (tmp, host->ioaddr +0x80 ); +}No defines for this? This is not terribly readable.
it was only temporary to ensure that if people bisected before the clock callback was added the host would at least work even if it was locked to one clock input.
Quoted 6 lines
drivers/mmc/host/sdhci-s3c.c line 110
Quoted 3 lines
drivers/mmc/host/sdhci-s3c.c new file +3
-0+if (pdata->cfg_card) + pdata->cfg_card (ourhost->pdev, host->ioaddr, + ios, host->mmc->card);What's the deal here? Hosts shouldn't know more about the card than the MMC core tells them.
Depending on exactly which version, there's a number of configurations in the extra configuration registers that get changed, such as delays used for clock feedback which are meant to be chnaged when the speed of the card is changed. Unfortunately this changes depending on the chip model and possibly also on the board it is on.
The other is that it is possible that depending on the chip and board combination things like the GPIO driver-strength controls will need to be changed.
Quoted 2 lines
Since I have no hardware for this, could you take it upon you to handle support for these chips? I'd like a
MAINTAINERSpatch for that as well.
ok, i'll add it to the list.
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 5/7] SDHCI: Samsung SDHCI (HSMMC) driver
Quoted 16 lines · On Sun, 16 Nov 2008 00:03:02 +0000 Ben Dooks <[email protected]> wrote:
Quoted 8 lines · Pierre Ossman
drivers/mmc/host/sdhci-s3c.c line 110
Quoted 3 lines · On Mon, 03 Nov 2008 20:09:49 +0000 Ben Dooks <[email protected]> wrote:
drivers/mmc/host/sdhci-s3c.c new file +3
-0+if (pdata->cfg_card) + pdata->cfg_card (ourhost->pdev, host->ioaddr, + ios, host->mmc->card);What's the deal here? Hosts shouldn't know more about the card than the MMC core tells them.
Depending on exactly which version, there's a number of configurations in the extra configuration registers that get changed, such as delays used for clock feedback which are meant to be chnaged when the speed of the card is changed. Unfortunately this changes depending on the chip model and possibly also on the board it is on.
Quoted 3 lines
The other is that it is possible that depending on the chip and board combination things like the GPIO driver-strength controls will need to be changed.
I don't see where knowledge about the card gets into the picture here. All of this sounds like information that is gathered from platform data and/or ios information.
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerPATCH 6/7 SDHCI: Check DMA for overruns at end of transfer
In reply to Ben DooksAt the end of a transfer, check that the DMA engine in the SDHCI controller actually did what it was meant to and didn't overrun the end of the buffer.
This seems to be triggered by a timeout during an CMD25 (multiple block write) to a card. The mmc_block module then issues a command to find out how much data was moved and this seems to end up triggering this DMA check. The result is the card's queue generates an OOPS as the stack has been trampled on due to the extra data transfered.
drivers/mmc/host/sdhci.c +19 -0
@@ -736,6 +736,23 @@ static void sdhci_set_transfer_mode(struwritew (mode, host->ioaddr +SDHCI_TRANSFER_MODE ); } +static void shdci_check_dma_overrun (struct sdhci_host *host,struct mmc_data *data) +{ +u32 dma_pos =readl (host->ioaddr +SDHCI_DMA_ADDRESS ); +u32 dma_start =sg_dma_address (data->sg); +u32 dma_end = dma_start + data->sg->length; + +/* Test whether we ended up moving more data than +* was originally requested. */ + +if (dma_pos <= dma_end) +return ; + +printk (KERN_ERR "%s: dma overrun, dma %08x, req %08x..%08x\n" , +mmc_hostname (host->mmc), dma_pos, + dma_start, dma_end); +} +static void sdhci_finish_data (struct sdhci_host *host) {struct mmc_data *data;
@@ -749,6 +766,8 @@ static void sdhci_finish_data(struct sdhif (host->flags &SDHCI_USE_ADMA )sdhci_adma_table_post (host, data);else { +shdci_check_dma_overrun (host, data); +dma_unmap_sg (mmc_dev (host->mmc), data->sg, data->sg_len, (data->flags &MMC_DATA_READ ) ?DMA_FROM_DEVICE :DMA_TO_DEVICE );
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
Maybe I didn't understand it right, but if the DMA controller could overrun a buffer, don't you ALSO need to add defensive padding (i.e. increase the buffer) to make sure nothing important gets overrun?
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Ben Dooks
maintainerRe: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
Quoted 3 lines · Henrique de Moraes Holschuh
Maybe I didn't understand it right, but if the DMA controller could overrun a buffer, don't you ALSO need to add defensive padding (i.e. increase the buffer) to make sure nothing important gets overrun?
This is only generated by problems elsewhere in the driver, such as getting the timeout clock wrong. It is here just as a precaution and as an aide to debugging, it should not trigger in normal circumstances.
There is a seperate problem where the DMA buffer is passed from the stack which is, IIRC, a complete no-no under Linux.
Signature · 4 lines
Ben Q: What's a light-year? A: One-third less calories than a regular year.
Re: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
Quoted 8 lines · Ben Dooks
Quoted 3 lines · Henrique de Moraes Holschuh
Maybe I didn't understand it right, but if the DMA controller could overrun a buffer, don't you ALSO need to add defensive padding (i.e. increase the buffer) to make sure nothing important gets overrun?
This is only generated by problems elsewhere in the driver, such as getting the timeout clock wrong. It is here just as a precaution and as an aide to debugging, it should not trigger in normal circumstances.
Then why is it just a WARN_ON, since you had a rogue DMA operation overwriting unknown kernel memory? Seems like an outright BUG_ON to me.
Quoted 2 lines
There is a seperate problem where the DMA buffer is passed from the stack which is, IIRC, a complete no-no under Linux.
Can't say much on that. I just found it strange that something as damaging as an overrun was only getting a WARN_ON and no defensive measure. If it is not going to happen normally, it might not require a defensive buffer, but once it happens, it looks like one must reboot ASAP from what you said...
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Re: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
Quoted 6 lines · Henrique de Moraes Holschuh
Quoted 5 lines · Ben Dooks
Quoted 3 lines · Henrique de Moraes Holschuh
Maybe I didn't understand it right, but if the DMA controller could overrun a buffer, don't you ALSO need to add defensive padding (i.e. increase the buffer) to make sure nothing important gets overrun?
Quoted 6 lines
Quoted 3 lines
This is only generated by problems elsewhere in the driver, such as getting the timeout clock wrong. It is here just as a precaution and as an aide to debugging, it should not trigger in normal circumstances.
Then why is it just a
WARN_ON, since you had a rogue DMA operation overwriting unknown kernel memory? Seems like an outrightBUG_ONto me.
It is a problem, but it doesn't kill the entire system. We could print it at a higher level. The WARN_ON()/BUG_ON() where not appropriate, as we do not need a whole stack backtrace, and I belive the mmc block thread somehow seems to manage to keep running even with an OOPS.
Quoted 7 lines
Quoted 2 lines
There is a seperate problem where the DMA buffer is passed from the stack which is, IIRC, a complete no-no under Linux.
Can't say much on that. I just found it strange that something as damaging as an overrun was only getting a
WARN_ONand no defensive measure. If it is not going to happen normally, it might not require a defensive buffer, but once it happens, it looks like one must reboot ASAP from what you said...
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
In reply to Ben DooksQuoted 11 lines · On Mon, 03 Nov 2008 20:09:50 +0000 Ben Dooks <[email protected]> wrote:
At the end of a transfer, check that the DMA engine in the SDHCI controller actually did what it was meant to and didn't overrun the end of the buffer.
This seems to be triggered by a timeout during an CMD25 (multiple block write) to a card. The
mmc_blockmodule then issues a command to find out how much data was moved and this seems to end up triggering this DMA check. The result is the card's queue generates an OOPS as the stack has been trampled on due to the extra data transfered.Signed-off-by Ben Dooks <[email protected]>
I'm sorry, but I don't see how this is anywhere near acceptable. This should be a panic at the very least, and until this can be sorted out and avoided the driver should avoid using DMA on these chips.
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerRe: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
Quoted 13 lines · Pierre Ossman
Quoted 10 lines · On Mon, 03 Nov 2008 20:09:50 +0000 Ben Dooks <[email protected]> wrote:
At the end of a transfer, check that the DMA engine in the SDHCI controller actually did what it was meant to and didn't overrun the end of the buffer.
This seems to be triggered by a timeout during an CMD25 (multiple block write) to a card. The
mmc_blockmodule then issues a command to find out how much data was moved and this seems to end up triggering this DMA check. The result is the card's queue generates an OOPS as the stack has been trampled on due to the extra data transfered.
Quoted 5 lines
Quoted 1 line
Signed-off-by Ben Dooks <[email protected]>I'm sorry, but I don't see how this is anywhere near acceptable. This should be a panic at the very least, and until this can be sorted out and avoided the driver should avoid using DMA on these chips.
A panic won't help get the debug logs out of the kernel. This only turned up whilst debugging the controller, I got the timeout clock calculation wrong and thus ended up timing out pretty much all the CMD25s and seeing this problem.
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 6/7] SDHCI: Check DMA for overruns at end of transfer
Quoted 7 lines · On Sun, 16 Nov 2008 00:05:08 +0000 Ben Dooks <[email protected]> wrote:
Quoted 4 lines · Pierre Ossman
I'm sorry, but I don't see how this is anywhere near acceptable. This should be a panic at the very least, and until this can be sorted out and avoided the driver should avoid using DMA on these chips.
A panic won't help get the debug logs out of the kernel.
Indeed, but it will avoid corrupting the system.
Quoted 5 lines
This only
turned up whilst debugging the controller, I got the timeout clock calculation wrong and thus ended up timing out pretty much all the CMD25s and seeing this problem.
Just because you had to provoke it doesn't mean it won't appear under "normal" circumstances for others.
Until this problem is fully understood I think DMA should be turned off (or possibly needs to be explicitly forced on using Kconfig or a module parameter).
Do you have any contacts at Samsung that can help out here?
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerPATCH 7/7 SDHCI: Add change_clock callback for glue drivers
In reply to Ben DooksAdd a change_clock callback to allow drivers to update device specific clock selections and control registers when there is a change in clock.
Move the main part of sdhci_set_clock() to a new routine which can be called by the glue drivers to do the sdhci standard clock management.
Update the sdhci-s3c driver to use this to select the appropriate clock source when clocks change.
drivers/mmc/host/sdhci-pci.c +1 -0
@@ -391,6 +391,7 @@ static int sdhci_pci_enable_dma(struct sstatic struct sdhci_ops sdhci_pci_ops = { .enable_dma = sdhci_pci_enable_dma, + .change_clock = sdhci_change_clock, };/*****************************************************************************\
drivers/mmc/host/sdhci-s3c.c +99 -18
172 lines not on this page · raw message
drivers/mmc/host/sdhci.c +10 -3
@@ -907,13 +907,18 @@ static void sdhci_finish_command(structstatic void sdhci_set_clock (struct sdhci_host *host,unsigned int clock) { +if (clock == host->clock) +return ; + + host->ops->change_clock (host, clock); +} + +void sdhci_change_clock (struct sdhci_host *host,unsigned int clock) +{int div;u16 clk;unsigned long timeout; -if (clock == host->clock) -return ; -writew (0 , host->ioaddr +SDHCI_CLOCK_CONTROL );if (clock ==0 )
@@ -950,6 +955,8 @@ out: host->clock = clock; } +EXPORT_SYMBOL_GPL (sdhci_set_clock); +static void sdhci_set_power (struct sdhci_host *host,unsigned short power) {u8 pwr;
drivers/mmc/host/sdhci.h +5 -0
@@ -273,6 +273,9 @@ struct sdhci_ops {unsigned int (*get_max_clock)(struct sdhci_host *host);unsigned int (*get_timeout_clock)(struct sdhci_host *host); +void (*change_clock)(struct sdhci_host *host, +unsigned int clock); +void (*set_ios)(struct sdhci_host *host,struct mmc_ios *ios); };
@@ -282,6 +285,8 @@ extern struct sdhci_host *sdhci_alloc_ho size_t priv_size);extern void sdhci_free_host (struct sdhci_host *host); +extern void sdhci_change_clock (struct sdhci_host *host,unsigned int clock); +static inline void *sdhci_priv (struct sdhci_host *host) {return (void *)host->private;
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 7/7] SDHCI: Add change_clock callback for glue drivers
Quoted 4 lines · On Mon, 03 Nov 2008 20:09:51 +0000 Ben Dooks <[email protected]> wrote:
Add a
change_clockcallback to allow drivers to update device specific clock selections and control registers when there is a change in clock.
Quoted 9 lines
Move the main part of
sdhci_set_clock()to a new routine which can be called by the glue drivers to do the sdhci standard clock management.Update the sdhci-s3c driver to use this to select the appropriate clock source when clocks change.
Signed-off-by Ben Dooks <[email protected]>
I'm afraid I don't quite follow on the requirements here. Care to elaborate as to why this is needed?
drivers/mmc/host/sdhci-pci.c static int sdhci_pci_enable_dma(struct s · line 397
Quoted 12 lines
Index:
linux.git/drivers/mmc/host/sdhci-pci.c
===================================================================drivers/mmc/host/sdhci-pci.c +1
-0@@ -391,6 +391,7 @@ static int sdhci_pci_enable_dma(struct sstatic struct sdhci_ops sdhci_pci_ops = { .enable_dma = sdhci_pci_enable_dma, + .change_clock = sdhci_change_clock, };/*****************************************************************************\
This seems pointless :)
drivers/mmc/host/sdhci-pci.c out: · line 959
Quoted 6 lines
drivers/mmc/host/sdhci-pci.c +2
-0@@ -950,6 +955,8 @@ out: host->clock = clock; } +EXPORT_SYMBOL_GPL (sdhci_set_clock); +
Wrong symbol. :)
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerRe: [patch 7/7] SDHCI: Add change_clock callback for glue drivers
Quoted 11 lines · Pierre Ossman
Quoted 8 lines · On Mon, 03 Nov 2008 20:09:51 +0000 Ben Dooks <[email protected]> wrote:
Add a
change_clockcallback to allow drivers to update device specific clock selections and control registers when there is a change in clock.Move the main part of
sdhci_set_clock()to a new routine which can be called by the glue drivers to do the sdhci standard clock management.
Quoted 8 lines
Quoted 5 lines
Update the sdhci-s3c driver to use this to select the appropriate clock source when clocks change.
Signed-off-by Ben Dooks <[email protected]>I'm afraid I don't quite follow on the requirements here. Care to elaborate as to why this is needed?
The controller has a number of possible clock sources, the bus clock it is connected to (generally called hclk) and three more clocks from the heirachy that is muxed/divided from either an 48MHz, 27MHz or the EPLL.
The callback allows the recalculation and selection of the best clock to run the card clock for the controller.
Quoted 15 lines
drivers/mmc/host/sdhci-pci.c static int sdhci_pci_enable_dma(struct s · line 397
Quoted 12 lines
Index:
linux.git/drivers/mmc/host/sdhci-pci.c
===================================================================drivers/mmc/host/sdhci-pci.c +1
-0@@ -391,6 +391,7 @@ static int sdhci_pci_enable_dma(struct sstatic struct sdhci_ops sdhci_pci_ops = { .enable_dma = sdhci_pci_enable_dma, + .change_clock = sdhci_change_clock, };/*****************************************************************************\ This seems pointless :)
Quoted 8 lines
drivers/mmc/host/sdhci-pci.c out: · line 959
Quoted 6 lines
drivers/mmc/host/sdhci-pci.c +2
-0@@ -950,6 +955,8 @@ out: host->clock = clock; } +EXPORT_SYMBOL_GPL (sdhci_set_clock); +Wrong symbol. :)
ok, will fix
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
Re: [patch 7/7] SDHCI: Add change_clock callback for glue drivers
Quoted 9 lines · On Sat, 15 Nov 2008 23:57:39 +0000 Ben Dooks <[email protected]> wrote:
The controller has a number of possible clock sources, the bus clock it is connected to (generally called hclk) and three more clocks from the heirachy that is muxed/divided from either an 48MHz, 27MHz or the EPLL.
The callback allows the recalculation and selection of the best clock to run the card clock for the controller.
Can these clock sources change mid-flight? Otherwise I don't see the need for a callback up to the sdhci core. But I don't see any connection points for such events.
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Ben Dooks
maintainerQuoted 2 lines · Ben Dooks
The following patch set gets working SDHCI on the
Samsung SoC series.
Any more comments on this, can these be merged for the -next branch?
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'