Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F168167437
D20197.id57173.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D20197.id57173.diff
View Options
Index: sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
===================================================================
--- sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
+++ sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
@@ -107,12 +107,14 @@
bus_dma_tag_t sc_dma_tag;
bus_dmamap_t sc_dma_map;
vm_paddr_t sc_sdhci_buffer_phys;
- uint32_t cmd_and_mode;
bus_addr_t dmamap_seg_addrs[NUM_DMA_SEGS];
bus_size_t dmamap_seg_sizes[NUM_DMA_SEGS];
int dmamap_seg_count;
int dmamap_seg_index;
int dmamap_status;
+ uint32_t blksz_and_count;
+ uint32_t cmd_and_mode;
+ bool need_update_blk;
};
static int bcm_sdhci_probe(device_t);
@@ -269,6 +271,10 @@
sdhci_start_slot(&sc->sc_slot);
+ /* Seed our copies. */
+ sc->blksz_and_count = SDHCI_READ_4(dev, &sc->sc_slot, SDHCI_BLOCK_SIZE);
+ sc->cmd_and_mode = SDHCI_READ_4(dev, &sc->sc_slot, SDHCI_TRANSFER_MODE);
+
return (0);
fail:
@@ -338,17 +344,21 @@
bcm_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
{
struct bcm_sdhci_softc *sc = device_get_softc(dev);
- uint32_t val = RD4(sc, off & ~3);
+ uint32_t val32;
/*
- * Standard 32-bit handling of command and transfer mode.
+ * Standard 32-bit handling of command and transfer mode, as
+ * well as block size and count.
*/
- if (off == SDHCI_TRANSFER_MODE) {
- return (sc->cmd_and_mode >> 16);
- } else if (off == SDHCI_COMMAND_FLAGS) {
- return (sc->cmd_and_mode & 0x0000ffff);
- }
- return ((val >> (off & 3)*8) & 0xffff);
+ if ((off == SDHCI_BLOCK_SIZE || off == SDHCI_BLOCK_COUNT) &&
+ sc->need_update_blk)
+ val32 = sc->blksz_and_count;
+ else if (off == SDHCI_TRANSFER_MODE || off == SDHCI_COMMAND_FLAGS)
+ val32 = sc->cmd_and_mode;
+ else
+ val32 = RD4(sc, off & ~3);
+
+ return ((val32 >> (off & 3)*8) & 0xffff);
}
static uint32_t
@@ -383,18 +393,43 @@
{
struct bcm_sdhci_softc *sc = device_get_softc(dev);
uint32_t val32;
- if (off == SDHCI_COMMAND_FLAGS)
+
+ /*
+ * If we have a queued up 16bit value for blk size or count, use and
+ * update the saved value rather than doing any real register access.
+ * If we did not touch either since the last write, then read from
+ * register as at least block count can change.
+ * Similarly, if we are about to issue a command, always use the saved
+ * value for transfer mode as we can never write that without issuing
+ * a command.
+ */
+ if ((off == SDHCI_BLOCK_SIZE || off == SDHCI_BLOCK_COUNT) &&
+ sc->need_update_blk)
+ val32 = sc->blksz_and_count;
+ else if (off == SDHCI_COMMAND_FLAGS)
val32 = sc->cmd_and_mode;
else
val32 = RD4(sc, off & ~3);
+
val32 &= ~(0xffff << (off & 3)*8);
val32 |= (val << (off & 3)*8);
+
if (off == SDHCI_TRANSFER_MODE)
sc->cmd_and_mode = val32;
- else {
- WR4(sc, off & ~3, val32);
- if (off == SDHCI_COMMAND_FLAGS)
+ else if (off == SDHCI_BLOCK_SIZE || off == SDHCI_BLOCK_COUNT) {
+ sc->blksz_and_count = val32;
+ sc->need_update_blk = true;
+ } else {
+ if (off == SDHCI_COMMAND_FLAGS) {
+ /* If we saved blk writes, do them now before cmd. */
+ if (sc->need_update_blk) {
+ WR4(sc, SDHCI_BLOCK_SIZE, sc->blksz_and_count);
+ sc->need_update_blk = false;
+ }
+ /* Always save cmd and mode registers. */
sc->cmd_and_mode = val32;
+ }
+ WR4(sc, off & ~3, val32);
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Aug 27, 4:46 PM (4 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37402499
Default Alt Text
D20197.id57173.diff (3 KB)
Attached To
Mode
D20197: bcm2835_sdhci.c: save block registers to avoid controller bug
Attached
Detach File
Event Timeline
Log In to Comment