Skip to content

Commit

Permalink
mmc: Add JZ4770 driver from Ingenic
Browse files Browse the repository at this point in the history
Taken from linux-2.6.31.3-jz-20110809-FR1.patch.gz.
Only the drivers relevant to JZ4770 are included.

The capacity hacks controlled by CONFIG_JZ_BOOT_FROM_MSC0 were omitted.
All except one were within "#if 0" blocks.

Greatly reduced amount of MMC/SD Kconfig options:
These all controlled things that should be specified in the platform data
structs in board support file instead.

Kconfig cleanups, make it more like JZ4740:
Renamed MMC_JZSOC to MMC_JZ4770.
Improved descriptions and help texts.
Only show JZ_SYSTEM_AT_CARD if the driver is selected.

Removed unused function. The comment said "for Atheros wifi", so it is
probably intended for some SDIO card. However, we don't have it so it's
better to remove the code than keep it with us unmaintained.

Removed feature to write-protect part of the SD card.
I don't see why this would have to be a driver feature.

Converted to use module_platform_driver(). It previously used
subsys_initcall(), but the MMC subsystem doesn't have to be
initialized early.

Return error code instead of starting an endless loop.

Register definitions are now part of the driver, not part of the
platform headers, since only this one driver should be touching
the MSC registers.

Various cleanups, such as removing includes where a struct declaration
suffices and removing function pointers that always point to the same
function.

Removed unnecessary BUG_ON check that triggered when the physical
address is in highmem.

Stripped header so only platform data definition remains.

JZ4770: Customize GPIO pins using data instead of callbacks.
Used an approach similar to the JZ4740 driver. The platform data
describes which GPIO pins are used and whether they are high or low
active, the driver will then manage those pins.

Use two-edge interrupt trigger. This feature is already emulated in
our interrupt controller driver, no need to emulate it again in the
MMC driver.

Removed PIO support. We only want to use DMA in production and having
the extra code present complicates refactoring.

Declare jz_mmc_detect() in header.

Handle power management using struct dev_pm_ops.

Removed debug code from jz_mmc_main.c.

Inline jz_mmc_controller_(de)init.

Renamed "plat" field to the more conventional "pdata".

Clean up probe function.
Make it more like the jz4740 driver's probe function.
Also use devres where possible.
No need to set drvdata to NULL, the kernel does that for us.
And don't pretend that DMA is optional.

Store struct jz_mmc_host as drvdata.
The original driver stored struct mmc_host instead.
Also removed redundant NULL checks: if the drvdata is NULL, the driver
is not operational and these functions will not be called.

Handle clock and power more like JZ4740 driver.
The set_ios handler is where it all happens.
For some reason, the driver hangs at initialisation if the reset is
performed with disabled device clock. I haven't figured out yet why,
but I have reduced the time that the clock is enabled to a minimum.

Eliminate CONFIG_JZ_SYSTEM_AT_CARD.
Instead of a compile-time option and hardcoded to MSC0, look at the
platform data: if there is no status_irq defined, treat it as an
always-present card.

Refuse to probe without platform data.
There is really no way we can run without knowing which GPIO pins to
use, so don't even try. By bailing out early we can avoid checks later.
Also print an error message if we refuse to probe because of an invalid
device ID.

Put change detection IRQ request in its own function.
Also changed the order of host and pdev arguments for the other request
functions, to be consistent with the JZ4740 driver.

Leave change detection to generic MMC code.

Removed unused fields from platform data.

Removed redundant max_bus_width platform data field.
Instead, set bus width capabilities based on the bus_width field.

Use slot-gpio implementations of read-only and change detect.
Also updated GPIO labels to use the same name that slot-gpio does
(device name instead of host name).

Enable erase capability.

Added "nonremovable" flag to platform data.

Removed semaphore around requests. The MMC framework already serializes
requests, there is no need to enforce this again in the host driver.

Removed unused #defines from internal header.

Don't log when a nonremovable card lacks change detect.

Use standard name for DMA descriptor struct.
Instead of using a macro, use the name directly, including "struct".
This is required now that the platform header no longer has a typedef.
Also moved inclusion of the DMA header to jz_mmc_dma.c, since that is
the only source file that actually has to know about DMA.

Include DMAC header explicitly.

Use generic clock API to get rate.
Also use the clock that actually belongs to the host in question,
instead of a hardcoded MSC0.
  • Loading branch information
mthuurne committed Nov 4, 2013
1 parent 6515d08 commit 0a1be0e
Show file tree
Hide file tree
Showing 13 changed files with 2,198 additions and 0 deletions.
39 changes: 39 additions & 0 deletions arch/mips/include/asm/mach-jz4770/mmc.h
@@ -0,0 +1,39 @@
/*
* arch/mips/include/asm/mach-jz4770/mmc.h
*
* JZ4770 MMC/SD Controller platform data
*
* Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
*/

#ifndef __ASM_MACH_JZ4770_MMC_H__
#define __ASM_MACH_JZ4770_MMC_H__

struct jz_mmc_platform_data {
unsigned int ocr_mask; /* available voltages */
unsigned char support_sdio;
unsigned char bus_width;

int gpio_card_detect;
int gpio_read_only;
int gpio_power;
unsigned card_detect_active_low:1;
unsigned read_only_active_low:1;
unsigned power_active_low:1;

/*
* Set this if the card cannot be physically removed from the device.
*/
unsigned nonremovable:1;

/*
* Each of the three MMC/SD Controllers can either use a private pin
* section with 4 data pins, or a shared pin section with 8 data pins.
* Set this flag if this MSC is the one using the shared pins.
* Note that there are 8 data pins available, but bus_width determines
* how many are actually used.
*/
unsigned use_shared_8bit_pins:1;
};

#endif /* __ASM_MACH_JZ4770_MMC_H__ */
9 changes: 9 additions & 0 deletions drivers/mmc/host/Kconfig
Expand Up @@ -603,6 +603,15 @@ config MMC_JZ4740
If you have a board based on such a SoC and with a SD/MMC slot, If you have a board based on such a SoC and with a SD/MMC slot,
say Y or M here. say Y or M here.


config MMC_JZ4770
tristate "JZ4770 SD/Multimedia Card Interface support"
depends on MACH_JZ4770
help
This selects support for the SD/MMC controller on Ingenic JZ4770
SoCs.
If you have a board based on such a SoC and with a SD/MMC slot,
say Y or M here.

config MMC_VUB300 config MMC_VUB300
tristate "VUB300 USB to SDIO/SD/MMC Host Controller support" tristate "VUB300 USB to SDIO/SD/MMC Host Controller support"
depends on USB depends on USB
Expand Down
1 change: 1 addition & 0 deletions drivers/mmc/host/Makefile
Expand Up @@ -46,6 +46,7 @@ obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o
obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
obj-$(CONFIG_MMC_JZ4770) += jzmmc/
obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_VUB300) += vub300.o
obj-$(CONFIG_MMC_USHC) += ushc.o obj-$(CONFIG_MMC_USHC) += ushc.o
obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o
Expand Down
8 changes: 8 additions & 0 deletions drivers/mmc/host/jzmmc/Makefile
@@ -0,0 +1,8 @@
#
# Makefile for MMC/SD host controller drivers
#

obj-$(CONFIG_MMC_JZ4770) += jz_mmc_main.o \
jz_mmc_msc.o \
jz_mmc_dma.o \
jz_mmc_gpio.o
178 changes: 178 additions & 0 deletions drivers/mmc/host/jzmmc/include/chip-msc.h
@@ -0,0 +1,178 @@
/*
* drivers/mmc/host/jzmmc/include/chip-msc.h
*
* JZ4770 MSC register definition.
*
* Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
*/

#ifndef __CHIP_MSC_H__
#define __CHIP_MSC_H__

#include <asm/mach-jz4770/jz4770misc.h>


#define MSC0_BASE 0xB0021000
#define MSC1_BASE 0xB0022000
#define MSC2_BASE 0xB0023000


/* n = 0, 1 (MSC0, MSC1) */
#define MSC_STRPCL(n) (MSC0_BASE + (n)*0x1000 + 0x000)
#define MSC_STAT(n) (MSC0_BASE + (n)*0x1000 + 0x004)
#define MSC_CLKRT(n) (MSC0_BASE + (n)*0x1000 + 0x008)
#define MSC_CMDAT(n) (MSC0_BASE + (n)*0x1000 + 0x00C)
#define MSC_RESTO(n) (MSC0_BASE + (n)*0x1000 + 0x010)
#define MSC_RDTO(n) (MSC0_BASE + (n)*0x1000 + 0x014)
#define MSC_BLKLEN(n) (MSC0_BASE + (n)*0x1000 + 0x018)
#define MSC_NOB(n) (MSC0_BASE + (n)*0x1000 + 0x01C)
#define MSC_SNOB(n) (MSC0_BASE + (n)*0x1000 + 0x020)
#define MSC_IMASK(n) (MSC0_BASE + (n)*0x1000 + 0x024)
#define MSC_IREG(n) (MSC0_BASE + (n)*0x1000 + 0x028)
#define MSC_CMD(n) (MSC0_BASE + (n)*0x1000 + 0x02C)
#define MSC_ARG(n) (MSC0_BASE + (n)*0x1000 + 0x030)
#define MSC_RES(n) (MSC0_BASE + (n)*0x1000 + 0x034)
#define MSC_RXFIFO(n) (MSC0_BASE + (n)*0x1000 + 0x038)
#define MSC_TXFIFO(n) (MSC0_BASE + (n)*0x1000 + 0x03C)
#define MSC_LPM(n) (MSC0_BASE + (n)*0x1000 + 0x040)

#define REG_MSC_STRPCL(n) REG16(MSC_STRPCL(n))
#define REG_MSC_STAT(n) REG32(MSC_STAT(n))
#define REG_MSC_CLKRT(n) REG16(MSC_CLKRT(n))
#define REG_MSC_CMDAT(n) REG32(MSC_CMDAT(n))
#define REG_MSC_RESTO(n) REG16(MSC_RESTO(n))
#define REG_MSC_RDTO(n) REG32(MSC_RDTO(n))
#define REG_MSC_BLKLEN(n) REG16(MSC_BLKLEN(n))
#define REG_MSC_NOB(n) REG16(MSC_NOB(n))
#define REG_MSC_SNOB(n) REG16(MSC_SNOB(n))
#define REG_MSC_IMASK(n) REG32(MSC_IMASK(n))
#define REG_MSC_IREG(n) REG16(MSC_IREG(n))
#define REG_MSC_CMD(n) REG8(MSC_CMD(n))
#define REG_MSC_ARG(n) REG32(MSC_ARG(n))
#define REG_MSC_RES(n) REG16(MSC_RES(n))
#define REG_MSC_RXFIFO(n) REG32(MSC_RXFIFO(n))
#define REG_MSC_TXFIFO(n) REG32(MSC_TXFIFO(n))
#define REG_MSC_LPM(n) REG32(MSC_LPM(n))

/* MSC Clock and Control Register (MSC_STRPCL) */
#define MSC_STRPCL_SEND_CCSD (1 << 15) /*send command completion signal disable to ceata */
#define MSC_STRPCL_SEND_AS_CCSD (1 << 14) /*send internally generated stop after sending ccsd */
#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7)
#define MSC_STRPCL_EXIT_TRANSFER (1 << 6)
#define MSC_STRPCL_START_READWAIT (1 << 5)
#define MSC_STRPCL_STOP_READWAIT (1 << 4)
#define MSC_STRPCL_RESET (1 << 3)
#define MSC_STRPCL_START_OP (1 << 2)
#define MSC_STRPCL_CLOCK_CONTROL_BIT 0
#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
#define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
#define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */

/* MSC Status Register (MSC_STAT) */
#define MSC_STAT_AUTO_CMD_DONE (1 << 31) /*12 is internally generated by controller has finished */
#define MSC_STAT_IS_RESETTING (1 << 15)
#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14)
#define MSC_STAT_PRG_DONE (1 << 13)
#define MSC_STAT_DATA_TRAN_DONE (1 << 12)
#define MSC_STAT_END_CMD_RES (1 << 11)
#define MSC_STAT_DATA_FIFO_AFULL (1 << 10)
#define MSC_STAT_IS_READWAIT (1 << 9)
#define MSC_STAT_CLK_EN (1 << 8)
#define MSC_STAT_DATA_FIFO_FULL (1 << 7)
#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6)
#define MSC_STAT_CRC_RES_ERR (1 << 5)
#define MSC_STAT_CRC_READ_ERROR (1 << 4)
#define MSC_STAT_CRC_WRITE_ERROR_BIT 2
#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
#define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
#define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
#define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
#define MSC_STAT_TIME_OUT_RES (1 << 1)
#define MSC_STAT_TIME_OUT_READ (1 << 0)

/* MSC Bus Clock Control Register (MSC_CLKRT) */
#define MSC_CLKRT_CLK_RATE_BIT 0
#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT)
#define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
#define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */

/* MSC Command Sequence Control Register (MSC_CMDAT) */
#define MSC_CMDAT_CCS_EXPECTED (1 << 31) /* interrupts are enabled in ce-ata */
#define MSC_CMDAT_READ_CEATA (1 << 30)
#define MSC_CMDAT_SDIO_PRDT (1 << 17) /* exact 2 cycle */
#define MSC_CMDAT_SEND_AS_STOP (1 << 16)
#define MSC_CMDAT_RTRG_BIT 14
#define MSC_CMDAT_RTRG_EQUALT_8 (0x0 << MSC_CMDAT_RTRG_BIT) /*reset value*/
#define MSC_CMDAT_RTRG_EQUALT_16 (0x1 << MSC_CMDAT_RTRG_BIT)
#define MSC_CMDAT_RTRG_EQUALT_24 (0x2 << MSC_CMDAT_RTRG_BIT)
#define MSC_CMDAT_TTRG_BIT 12
#define MSC_CMDAT_TTRG_LESS_8 (0x0 << MSC_CMDAT_TTRG_BIT) /*reset value*/
#define MSC_CMDAT_TTRG_LESS_16 (0x1 << MSC_CMDAT_TTRG_BIT)
#define MSC_CMDAT_TTRG_LESS_24 (0x2 << MSC_CMDAT_TTRG_BIT)
#define MSC_CMDAT_STOP_ABORT (1 << 11)
#define MSC_CMDAT_BUS_WIDTH_BIT 9
#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) /* 1-bit data bus */
#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) /* 4-bit data bus */
#define MSC_CMDAT_BUS_WIDTH_8BIT (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) /* 8-bit data bus */
#define MSC_CMDAT_DMA_EN (1 << 8)
#define MSC_CMDAT_INIT (1 << 7)
#define MSC_CMDAT_BUSY (1 << 6)
#define MSC_CMDAT_STREAM_BLOCK (1 << 5)
#define MSC_CMDAT_WRITE (1 << 4)
#define MSC_CMDAT_READ (0 << 4)
#define MSC_CMDAT_DATA_EN (1 << 3)
#define MSC_CMDAT_RESPONSE_BIT 0
#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT)
#define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) /* No response */
#define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) /* Format R1 and R1b */
#define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) /* Format R2 */
#define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) /* Format R3 */
#define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) /* Format R4 */
#define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) /* Format R5 */
#define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) /* Format R6 */
#define MSC_CMDAT_RESRONSE_R7 (0x7 << MSC_CMDAT_RESPONSE_BIT) /* Format R7 */

/* MSC Interrupts Mask Register (MSC_IMASK) */
#define MSC_IMASK_AUTO_CMD_DONE (1 << 15)
#define MSC_IMASK_DATA_FIFO_FULL (1 << 14)
#define MSC_IMASK_DATA_FIFO_EMP (1 << 13)
#define MSC_IMASK_CRC_RES_ERR (1 << 12)
#define MSC_IMASK_CRC_READ_ERR (1 << 11)
#define MSC_IMASK_CRC_WRITE_ERR (1 << 10)
#define MSC_IMASK_TIME_OUT_RES (1 << 9)
#define MSC_IMASK_TIME_OUT_READ (1 << 8)
#define MSC_IMASK_SDIO (1 << 7)
#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6)
#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5)
#define MSC_IMASK_END_CMD_RES (1 << 2)
#define MSC_IMASK_PRG_DONE (1 << 1)
#define MSC_IMASK_DATA_TRAN_DONE (1 << 0)

/* MSC Interrupts Status Register (MSC_IREG) */
#define MSC_IREG_AUTO_CMD_DONE (1 << 15)
#define MSC_IREG_DATA_FIFO_FULL (1 << 14)
#define MSC_IREG_DATA_FIFO_EMP (1 << 13)
#define MSC_IREG_CRC_RES_ERR (1 << 12)
#define MSC_IREG_CRC_READ_ERR (1 << 11)
#define MSC_IREG_CRC_WRITE_ERR (1 << 10)
#define MSC_IREG_TIMEOUT_RES (1 << 9)
#define MSC_IREG_TIMEOUT_READ (1 << 8)
#define MSC_IREG_SDIO (1 << 7)
#define MSC_IREG_TXFIFO_WR_REQ (1 << 6)
#define MSC_IREG_RXFIFO_RD_REQ (1 << 5)
#define MSC_IREG_END_CMD_RES (1 << 2)
#define MSC_IREG_PRG_DONE (1 << 1)
#define MSC_IREG_DATA_TRAN_DONE (1 << 0)

/* MSC Low Power Mode Register (MSC_LPM) */
#define MSC_SET_HISPD (1 << 31)
#define MSC_SET_LPM (1 << 0)

#endif /* __CHIP_MSC_H__ */
28 changes: 28 additions & 0 deletions drivers/mmc/host/jzmmc/include/jz_mmc_dma.h
@@ -0,0 +1,28 @@
/*
* linux/drivers/mmc/host/jz_mmc/dma/jz_mmc_dma.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Copyright (c) Ingenic Semiconductor Co., Ltd.
*/

#ifndef __JZ_MMC_DMA_H__
#define __JZ_MMC_DMA_H__

struct jz_mmc_host;

void jz_mmc_start_dma(struct jz_mmc_host *host);
void jz_mmc_stop_dma(struct jz_mmc_host *host);

void jz_mmc_start_normal_dma(struct jz_mmc_host *host, unsigned long phyaddr,
int count, int mode, int ds);
void jz_mmc_start_scatter_dma(int chan, struct jz_mmc_host *host,
struct scatterlist *sg, unsigned int sg_len,
int mode);

int jz_mmc_init_dma(struct jz_mmc_host *host);
void jz_mmc_deinit_dma(struct jz_mmc_host *host);

#endif /* __JZ_MMC_DMA_H__ */
20 changes: 20 additions & 0 deletions drivers/mmc/host/jzmmc/include/jz_mmc_gpio.h
@@ -0,0 +1,20 @@
/*
* linux/drivers/mmc/host/jz_mmc/gpio/jz_mmc_gpio.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Copyright (c) Ingenic Semiconductor Co., Ltd.
*/

#ifndef __JZ_MMC_GPIO_H__
#define __JZ_MMC_GPIO_H__

struct jz_mmc_host;
struct platform_device;

int jz_mmc_gpio_init(struct jz_mmc_host *host, struct platform_device *pdev);
void jz_mmc_gpio_deinit(struct jz_mmc_host *host, struct platform_device *pdev);

#endif /* __JZ_MMC_GPIO_H__ */
71 changes: 71 additions & 0 deletions drivers/mmc/host/jzmmc/include/jz_mmc_host.h
@@ -0,0 +1,71 @@
/*
* linux/drivers/mmc/host/jz_mmc/jz_mmc_host.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Copyright (c) Ingenic Semiconductor Co., Ltd.
*/

#ifndef __JZ_MMC_HOST_H__
#define __JZ_MMC_HOST_H__

#define USE_DMA_DESC
//#define USE_DMA_UNCACHE
//#define MSC_DEBUG_DMA

#define USE_DMA_BUSRT_64

#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
#define SD_CLOCK_HIGH 48000000 /* 24 MHz for SD Cards */
#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */


struct clk;

struct jz_mmc_host {
struct mmc_host *mmc;

struct clk *clk;

/* host resources */
void __iomem *base;
unsigned int pdev_id;
int irq;
int dma_id;
struct jz_mmc_platform_data *pdata;

/* mmc request related */
unsigned int cmdat;
struct mmc_request *curr_mrq;
int curr_res_type;

/* data transter related */
struct {
int len;
int dir;
int channel;
} dma;
#ifdef USE_DMA_DESC
#ifdef MSC_DEBUG_DMA
int num_desc;
int last_direction;
#endif
struct jz_dma_desc_8word *dma_desc;
#endif
wait_queue_head_t data_wait_queue;
volatile int data_ack;
volatile int data_err;

/* card detect related */
int card_detect_irq;

/* labels for gpio pins */
char *label_power;
};

void jz_mmc_finish_request(struct jz_mmc_host *host, struct mmc_request *mrq);

#endif /* __JZ_MMC_HOST_H__ */

0 comments on commit 0a1be0e

Please sign in to comment.