summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/mmc/host/mmc_atsmb1.c
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/mmc/host/mmc_atsmb1.c')
-rwxr-xr-xANDROID_3.4.5/drivers/mmc/host/mmc_atsmb1.c2405
1 files changed, 0 insertions, 2405 deletions
diff --git a/ANDROID_3.4.5/drivers/mmc/host/mmc_atsmb1.c b/ANDROID_3.4.5/drivers/mmc/host/mmc_atsmb1.c
deleted file mode 100755
index 2cfefbcd..00000000
--- a/ANDROID_3.4.5/drivers/mmc/host/mmc_atsmb1.c
+++ /dev/null
@@ -1,2405 +0,0 @@
-/*++
-linux/drivers/mmc/host/mmc_atsmb1.c
-
-Copyright (c) 2008 WonderMedia Technologies, Inc.
-
-This program 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.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along with
-this program. If not, see <http://www.gnu.org/licenses/>.
-
-WonderMedia Technologies, Inc.
-10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-
-//#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sd.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/sdio.h>
-#include <linux/completion.h>
-#include <linux/pagemap.h>
-#include <linux/dma-mapping.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/scatterlist.h>
-#include <asm/sizes.h>
-#include "mmc_atsmb.h"
-//#include <mach/multicard.h>
-#include <mach/irqs.h>
-
-#define mprintk
-
-/* chcek emmc card is fist boot, 1:fisrt boot, 0:suspend/resume */
-int atsmb1_first_boot;
-#if 0
-#define DBG(host, fmt, args...) \
- pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
-#endif
-#define ATSMB_TIMEOUT_TIME (HZ*2)
-
-//add by jay,for modules support
-static u64 wmt_sdmmc1_dma_mask = 0xffffffffUL;
-static struct resource wmt_sdmmc1_resources[] = {
- [0] = {
- .start = SD1_SDIO_MMC_BASE_ADDR,
- .end = (SD1_SDIO_MMC_BASE_ADDR + 0x3FF),
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_SDC1,
- .end = IRQ_SDC1,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_SDC1_DMA,
- .end = IRQ_SDC1_DMA,
- .flags = IORESOURCE_IRQ,
- },
- /*2008/10/6 RichardHsu-s*/
- [3] = {
- .start = IRQ_PMC_WAKEUP,
- .end = IRQ_PMC_WAKEUP,
- .flags = IORESOURCE_IRQ,
- },
- /*2008/10/6 RichardHsu-e*/
-};
-
-
-//
-static void atsmb1_release(struct device * dev) {}
-
-/*#ifdef CONFIG_MMC_DEBUG*/
-#define MORE_INFO
-#if 0
-#define DBG(x...) printk(KERN_ALERT x)
-#define DBGR(x...) printk(KERN_ALERT x)
-#else
-#define DBG(x...) do { } while (0)
-#define DBGR(x...) do { } while (0)
-#endif
-
-/* when Read CRC error occur, and clear read CRC error by software reset.*/
-void atsmb1_copy_reg(int direct)
-{
- static u8 CTL, CMD_IDX, RSP_TYPE, BUS_MODE, INT_MASK_0, INT_MASK_1, SD_STS_0, SD_STS_1, SD_STS_2, SD_STS_3;
- static u8 EXT_BUS_MODE, EXT_CTL_1, EXT_CTL_2, MAN_TUNE_VAL, SD_WRI_TUNE;
- static u8 RSP_0, RSP_1, RSP_2, RSP_3, RSP_4, RSP_5, RSP_6, RSP_7;
- static u8 RSP_8, RSP_9, RSP_10, RSP_11, RSP_12, RSP_13, RSP_14, RSP_15;
- static u8 RSP_TOUT, CLK_SEL, EXT_CTL;
- static u16 BLK_LEN, BLK_CNT, SHDW_BLKLEN, TIMER_VAL, CTL2;
- static u32 CMD_ARG, CURBLK_CNT;
-
- /*direct 0: copy register to memory; 1: copy memory to register.*/
- if (direct == 0) {
- CTL = *ATSMB1_CTL;
- CMD_IDX = *ATSMB1_CMD_IDX;
- RSP_TYPE = *ATSMB1_RSP_TYPE;
- CMD_ARG = *ATSMB1_CMD_ARG;
- BUS_MODE = *ATSMB1_BUS_MODE;
- EXT_BUS_MODE = *ATSMB1_EXT_BUS_MODE;
- CTL2 = *ATSMB1_CTL2;
- BLK_LEN = *ATSMB1_BLK_LEN;
- BLK_CNT = *ATSMB1_BLK_CNT;
- RSP_0 = *ATSMB1_RSP_0;
- RSP_1 = *ATSMB1_RSP_1;
- RSP_2 = *ATSMB1_RSP_2;
- RSP_3 = *ATSMB1_RSP_3;
- RSP_4 = *ATSMB1_RSP_4;
- RSP_5 = *ATSMB1_RSP_5;
- RSP_6 = *ATSMB1_RSP_6;
- RSP_7 = *ATSMB1_RSP_7;
- RSP_8 = *ATSMB1_RSP_8;
- RSP_9 = *ATSMB1_RSP_9;
- RSP_10 = *ATSMB1_RSP_10;
- RSP_11 = *ATSMB1_RSP_11;
- RSP_12 = *ATSMB1_RSP_12;
- RSP_13 = *ATSMB1_RSP_13;
- RSP_14 = *ATSMB1_RSP_14;
- RSP_15 = *ATSMB1_RSP_15;
- CURBLK_CNT = *ATSMB1_CURBLK_CNT;
- INT_MASK_0 = *ATSMB1_INT_MASK_0;
- INT_MASK_1 = *ATSMB1_INT_MASK_1;
- SD_STS_0 = *ATSMB1_SD_STS_0;
- SD_STS_1 = *ATSMB1_SD_STS_1;
- SD_STS_2 = *ATSMB1_SD_STS_2;
- SD_STS_3 = *ATSMB1_SD_STS_3;
- RSP_TOUT = *ATSMB1_RSP_TOUT;
- CLK_SEL = *ATSMB1_CLK_SEL;
- EXT_CTL = *ATSMB1_EXT_CTL;
- EXT_CTL_1 = *ATSMB1_EXT_CTL_1;
- EXT_CTL_2 = *ATSMB1_EXT_CTL_2;
- SHDW_BLKLEN = *ATSMB1_SHDW_BLKLEN;
- MAN_TUNE_VAL = *ATSMB1_MAN_TUNE_VAL;
- SD_WRI_TUNE = *ATSMB1_SD_WRI_TUNE;
- TIMER_VAL = *ATSMB1_TIMER_VAL;
- } else {
- *ATSMB1_CTL = CTL;
- *ATSMB1_CMD_IDX = CMD_IDX;
- *ATSMB1_RSP_TYPE = RSP_TYPE;
- *ATSMB1_CMD_ARG = CMD_ARG;
- *ATSMB1_BUS_MODE = BUS_MODE;
- *ATSMB1_EXT_BUS_MODE = EXT_BUS_MODE;
- *ATSMB1_CTL2 = CTL2;
- *ATSMB1_BLK_LEN = BLK_LEN;
- *ATSMB1_BLK_CNT = BLK_CNT;
- *ATSMB1_RSP_0 = RSP_0;
- *ATSMB1_RSP_1 = RSP_1;
- *ATSMB1_RSP_2 = RSP_2;
- *ATSMB1_RSP_3 = RSP_3;
- *ATSMB1_RSP_4 = RSP_4;
- *ATSMB1_RSP_5 = RSP_5;
- *ATSMB1_RSP_6 = RSP_6;
- *ATSMB1_RSP_7 = RSP_7;
- *ATSMB1_RSP_8 = RSP_8;
- *ATSMB1_RSP_9 = RSP_9;
- *ATSMB1_RSP_10 = RSP_10;
- *ATSMB1_RSP_11 = RSP_11;
- *ATSMB1_RSP_12 = RSP_12;
- *ATSMB1_RSP_13 = RSP_13;
- *ATSMB1_RSP_14 = RSP_14;
- *ATSMB1_RSP_15 = RSP_15;
- *ATSMB1_CURBLK_CNT = CURBLK_CNT;
- *ATSMB1_INT_MASK_0 = INT_MASK_0;
- *ATSMB1_INT_MASK_1 = INT_MASK_1;
- *ATSMB1_SD_STS_0 = SD_STS_0;
- *ATSMB1_SD_STS_1 = SD_STS_1;
- *ATSMB1_SD_STS_2 = SD_STS_2;
- *ATSMB1_SD_STS_3 = SD_STS_3;
- *ATSMB1_RSP_TOUT = RSP_TOUT;
- *ATSMB1_CLK_SEL = CLK_SEL;
- *ATSMB1_EXT_CTL = EXT_CTL;
- *ATSMB1_EXT_CTL_1 = EXT_CTL_1;
- *ATSMB1_EXT_CTL_2 = EXT_CTL_2;
- *ATSMB1_SHDW_BLKLEN = SHDW_BLKLEN;
- *ATSMB1_MAN_TUNE_VAL = MAN_TUNE_VAL;
- *ATSMB1_SD_WRI_TUNE = SD_WRI_TUNE;
- *ATSMB1_TIMER_VAL = TIMER_VAL;
- }
-}
-
-#if 0
-void atsmb1_dump_reg(struct atsmb_host *host)
-{
- u8 CTL, CMD_IDX, RSP_TYPE, BUS_MODE, INT_MASK_0, INT_MASK_1, SD_STS_0, SD_STS_1, SD_STS_2, SD_STS_3;
- u8 EXT_BUS_MODE, EXT_CTL_1, EXT_CTL_2, MAN_TUNE_VAL, SD_WRI_TUNE;
- u8 RSP_0, RSP_1, RSP_2, RSP_3, RSP_4, RSP_5, RSP_6, RSP_7;
- u8 RSP_8, RSP_9, RSP_10, RSP_11, RSP_12, RSP_13, RSP_14, RSP_15;
- u8 RSP_TOUT, CLK_SEL, EXT_CTL;
- u16 BLK_LEN, BLK_CNT, SHDW_BLKLEN, TIMER_VAL, CTL2;
- u32 CMD_ARG, PDMA_GCR, PDMA_IER, PDMA_ISR, PDMA_DESPR, PDMA_RBR, PDMA_DAR, PDMA_BAR, PDMA_CPR, PDMA_CCR;
- u32 CURBLK_CNT;
-
- CTL = *ATSMB1_CTL;
- CMD_IDX = *ATSMB1_CMD_IDX;
- RSP_TYPE = *ATSMB1_RSP_TYPE;
- CMD_ARG = *ATSMB1_CMD_ARG;
- BUS_MODE = *ATSMB1_BUS_MODE;
- EXT_BUS_MODE = *ATSMB1_EXT_BUS_MODE;
- CTL2 = *ATSMB1_CTL2;
- BLK_LEN = *ATSMB1_BLK_LEN;
- BLK_CNT = *ATSMB1_BLK_CNT;
- RSP_0 = *ATSMB1_RSP_0;
- RSP_1 = *ATSMB1_RSP_1;
- RSP_2 = *ATSMB1_RSP_2;
- RSP_3 = *ATSMB1_RSP_3;
- RSP_4 = *ATSMB1_RSP_4;
- RSP_5 = *ATSMB1_RSP_5;
- RSP_6 = *ATSMB1_RSP_6;
- RSP_7 = *ATSMB1_RSP_7;
- RSP_8 = *ATSMB1_RSP_8;
- RSP_9 = *ATSMB1_RSP_9;
- RSP_10 = *ATSMB1_RSP_10;
- RSP_11 = *ATSMB1_RSP_11;
- RSP_12 = *ATSMB1_RSP_12;
- RSP_13 = *ATSMB1_RSP_13;
- RSP_14 = *ATSMB1_RSP_14;
- RSP_15 = *ATSMB1_RSP_15;
- CURBLK_CNT = *ATSMB1_CURBLK_CNT;
- INT_MASK_0 = *ATSMB1_INT_MASK_0;
- INT_MASK_1 = *ATSMB1_INT_MASK_1;
- SD_STS_0 = *ATSMB1_SD_STS_0;
- SD_STS_1 = *ATSMB1_SD_STS_1;
- SD_STS_2 = *ATSMB1_SD_STS_2;
- SD_STS_3 = *ATSMB1_SD_STS_3;
- RSP_TOUT = *ATSMB1_RSP_TOUT;
- CLK_SEL = *ATSMB1_CLK_SEL;
- EXT_CTL = *ATSMB1_EXT_CTL;
- EXT_CTL_1 = *ATSMB1_EXT_CTL_1;
- EXT_CTL_2 = *ATSMB1_EXT_CTL_2;
- SHDW_BLKLEN = *ATSMB1_SHDW_BLKLEN;
- MAN_TUNE_VAL = *ATSMB1_MAN_TUNE_VAL;
- SD_WRI_TUNE = *ATSMB1_SD_WRI_TUNE;
- TIMER_VAL = *ATSMB1_TIMER_VAL;
-
- PDMA_GCR = *ATSMB1_PDMA_GCR;
- PDMA_IER = *ATSMB1_PDMA_IER;
- PDMA_ISR = *ATSMB1_PDMA_ISR;
- PDMA_DESPR = *ATSMB1_PDMA_DESPR;
- PDMA_RBR = *ATSMB1_PDMA_RBR;
- PDMA_DAR = *ATSMB1_PDMA_DAR;
- PDMA_BAR = *ATSMB1_PDMA_BAR;
- PDMA_CPR = *ATSMB1_PDMA_CPR;
- PDMA_CCR = *ATSMB1_PDMA_CCR;
-
- DBGR("\n+---------------------------Registers----------------------------+\n");
-
- DBGR("%16s = 0x%8x |", "CTL", CTL);
- DBGR("%16s = 0x%8x\n", "CMD_IDX", CMD_IDX);
-
- DBGR("%16s = 0x%8x |", "RSP_TYPE", RSP_TYPE);
- DBGR("%16s = 0x%8x\n", "CMD_ARG", CMD_ARG);
-
- DBGR("%16s = 0x%8x |", "BUS_MODE", BUS_MODE);
- DBGR("%16s = 0x%8x\n", "EXT_BUS_MODE", EXT_BUS_MODE);
-
- DBGR("%16s = 0x%8x |", "CTL2", CTL2);
- DBGR("%16s = 0x%8x\n", "BLK_LEN", BLK_LEN);
-
- DBGR("%16s = 0x%8x |", "BLK_CNT", BLK_CNT);
- DBGR("%16s = 0x%8x\n", "RSP_0", RSP_0);
-
- DBGR("%16s = 0x%8x |", "RSP_1", RSP_1);
- DBGR("%16s = 0x%8x\n", "RSP_2", RSP_2);
-
- DBGR("%16s = 0x%8x |", "RSP_3", RSP_3);
- DBGR("%16s = 0x%8x\n", "RSP_4", RSP_4);
-
- DBGR("%16s = 0x%8x |", "RSP_5", RSP_5);
- DBGR("%16s = 0x%8x\n", "RSP_6", RSP_6);
-
- DBGR("%16s = 0x%8x |", "RSP_7", RSP_7);
- DBGR("%16s = 0x%8x\n", "RSP_8", RSP_8);
-
- DBGR("%16s = 0x%8x |", "RSP_9", RSP_9);
- DBGR("%16s = 0x%8x\n", "RSP_10", RSP_10);
-
- DBGR("%16s = 0x%8x |", "RSP_11", RSP_11);
- DBGR("%16s = 0x%8x\n", "RSP_12", RSP_12);
-
- DBGR("%16s = 0x%8x |", "RSP_13", RSP_13);
- DBGR("%16s = 0x%8x\n", "RSP_14", RSP_14);
-
- DBGR("%16s = 0x%8x\n", "RSP_15", RSP_15);
-
- DBGR("%16s = 0x%8x |", "CURBLK_CNT", CURBLK_CNT);
- DBGR("%16s = 0x%8x\n", "INT_MASK_0", INT_MASK_0);
-
- DBGR("%16s = 0x%8x |", "INT_MASK_1", INT_MASK_1);
- DBGR("%16s = 0x%8x\n", "SD_STS_0", SD_STS_0);
-
- DBGR("%16s = 0x%8x |", "SD_STS_1", SD_STS_1);
- DBGR("%16s = 0x%8x\n", "SD_STS_2", SD_STS_2);
-
- DBGR("%16s = 0x%8x |", "SD_STS_3", SD_STS_3);
- DBGR("%16s = 0x%8x\n", "RSP_TOUT", RSP_TOUT);
-
- DBGR("%16s = 0x%8x |", "CLK_SEL", CLK_SEL);
- DBGR("%16s = 0x%8x\n", "EXT_CTL", EXT_CTL);
-
- DBGR("%16s = 0x%8x |", "EXT_CTL_1", EXT_CTL_1);
- DBGR("%16s = 0x%8x\n", "EXT_CTL_2", EXT_CTL_2);
-
- DBGR("%16s = 0x%8x |", "SHDW_BLKLEN", SHDW_BLKLEN);
- DBGR("%16s = 0x%8x\n", "MAN_TUNE_VAL", MAN_TUNE_VAL);
-
- DBGR("%16s = 0x%8x |", "SD_WRI_TUNE", SD_WRI_TUNE);
- DBGR("%16s = 0x%8x\n", "TIMER_VAL", TIMER_VAL);
-
- DBGR("%16s = 0x%8x |", "PDMA_GCR", PDMA_GCR);
- DBGR("%16s = 0x%8x\n", "PDMA_IER", PDMA_IER);
-
- DBGR("%16s = 0x%8x |", "PDMA_ISR", PDMA_ISR);
- DBGR("%16s = 0x%8x\n", "PDMA_DESPR", PDMA_DESPR);
-
- DBGR("%16s = 0x%8x |", "PDMA_RBR", PDMA_RBR);
- DBGR("%16s = 0x%8x\n", "PDMA_DAR", PDMA_DAR);
-
- DBGR("%16s = 0x%8x |", "PDMA_BAR", PDMA_BAR);
- DBGR("%16s = 0x%8x\n", "PDMA_CPR", PDMA_CPR);
-
- DBGR("%16s = 0x%8x |", "PDMA_CCR", PDMA_CCR);
- DBGR("\n+----------------------------------------------------------------+\n");
-}
-#else
-void atsmb1_dump_reg(struct atsmb_host *host) {}
-#endif
-
-unsigned int fmax1 = 515633;
-unsigned int MMC1_DRIVER_VERSION;
-int SD1_function = 0; /*0: normal SD/MMC card reader*/
-int SDXC1_function;
-
-
-int SCC1_ID(void){
- unsigned short val;
-
- val = REG16_VAL(SYSTEM_CFG_CTRL_BASE_ADDR + 0x2);
- return val;
-}
-
-int get_chip_version1(void) /*2008/05/01 janshiue modify for A1 chip*/
-{
- u32 tmp;
-
- tmp = REG32_VAL(SYSTEM_CFG_CTRL_BASE_ADDR);
- tmp = ((tmp & 0xF00) >> 4) + 0x90 + ((tmp & 0xFF) - 1);
- return tmp;
-}
-
-void get_driver_version1(void)
-{
- if (SCC1_ID() == 0x3426) {
- if (get_chip_version1() < 0xA1)
- MMC1_DRIVER_VERSION = MMC_DRV_3426_A0;
- else if (get_chip_version1() == 0xA1)
- MMC1_DRIVER_VERSION = MMC_DRV_3426_A1;
- else
- MMC1_DRIVER_VERSION = MMC_DRV_3426_A2;
- } else if (SCC1_ID() == 0x3437) {
- if (get_chip_version1() < 0xA1)
- MMC1_DRIVER_VERSION = MMC_DRV_3437_A0;
- else
- MMC1_DRIVER_VERSION = MMC_DRV_3437_A1;
- } else if (SCC1_ID() == 0x3429) {
- MMC1_DRIVER_VERSION = MMC_DRV_3429;
- } else if (SCC1_ID() == 0x3451) {
- if (get_chip_version1() < 0xA1)
- MMC1_DRIVER_VERSION = MMC_DRV_3451_A0;
- } else if (SCC1_ID() == 0x3465) {
- MMC1_DRIVER_VERSION = MMC_DRV_3465;
- } else if (SCC1_ID() == 0x3445) {
- MMC1_DRIVER_VERSION = MMC_DRV_3445;
- } else if (SCC1_ID() == 0x3481) {
- MMC1_DRIVER_VERSION = MMC_DRV_3481;
- } else if (SCC1_ID() == 0x3498) {
- MMC1_DRIVER_VERSION = MMC_DRV_3498;
- }
-}
-/*2008/10/6 RichardHsu-e*/
-
-/**********************************************************************
-Name : atsmb1_alloc_desc
-Function : To config PDMA descriptor setting.
-Calls :
-Called by :
-Parameter :
-Author : Janshiue Wu
-History :
-***********************************************************************/
-static inline int atsmb1_alloc_desc(struct atsmb_host *host,
- unsigned int bytes)
-{
- void *DescPool = NULL;
- DBG("[%s] s\n",__func__);
-
- DescPool = dma_alloc_coherent(host->mmc->parent, bytes, &(host->DescPhyAddr), GFP_KERNEL);
- if (!DescPool) {
- DBG("can't allocal desc pool=%8X %8X\n", DescPool, host->DescPhyAddr);
- DBG("[%s] e1\n",__func__);
- return -1;
- }
- DBG("allocal desc pool=%8X %8X\n", DescPool, host->DescPhyAddr);
- host->DescVirAddr = (unsigned long *)DescPool;
- host->DescSize = bytes;
- DBG("[%s] e2\n",__func__);
- return 0;
-}
-
-/**********************************************************************
-Name : atsmb1_config_desc
-Function : To config PDMA descriptor setting.
-Calls :
-Called by :
-Parameter :
-Author : Janshiue Wu
-History :
-***********************************************************************/
-static inline void atsmb1_config_desc(unsigned long *DescAddr,
- unsigned long *BufferAddr,
- unsigned long Blk_Cnt)
-{
-
- int i = 0 ;
- unsigned long *CurDes = DescAddr;
- DBG("[%s] s\n",__func__);
-
- /* the first Descriptor store for 1 Block data
- * (512 bytes)
- */
- for (i = 0 ; i < 3 ; i++) {
- atsmb1_init_short_desc(CurDes, 0x80, BufferAddr, 0);
- BufferAddr += 0x20;
- CurDes += sizeof(struct SD_PDMA_DESC_S)/4;
- }
- if (Blk_Cnt > 1) {
- atsmb1_init_long_desc(CurDes, 0x80, BufferAddr, CurDes + (sizeof(struct SD_PDMA_DESC_L)/4), 0);
- BufferAddr += 0x20;
- CurDes += sizeof(struct SD_PDMA_DESC_L)/4;
- /* the following Descriptor store the rest Blocks data
- * (Blk_Cnt - 1) * 512 bytes
- */
- atsmb1_init_long_desc(CurDes, (Blk_Cnt - 1) * 512,
- BufferAddr, CurDes + (sizeof(struct SD_PDMA_DESC_L)/4), 1);
- } else {
- atsmb1_init_long_desc(CurDes, 0x80, BufferAddr, CurDes + (sizeof(struct SD_PDMA_DESC_L)/4), 1);
- }
- DBG("[%s] e\n",__func__);
-}
-/**********************************************************************
-Name : atsmb1_config_dma
-Function : To set des/src address, byte count to transfer, and DMA channel settings,
- and DMA ctrl. register.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static inline void atsmb1_config_dma(unsigned long config_dir,
- unsigned long dma_mask,
- struct atsmb_host *host)
-{
- DBG("[%s] s\n",__func__);
-
- /* Enable DMA */
- *ATSMB1_PDMA_GCR = SD_PDMA_GCR_DMA_EN;
- *ATSMB1_PDMA_GCR = SD_PDMA_GCR_SOFTRESET;
- *ATSMB1_PDMA_GCR = SD_PDMA_GCR_DMA_EN;
- /*open interrupt*/
- *ATSMB1_PDMA_IER = SD_PDMA_IER_INT_EN;
- /*Make sure host could co-work with DMA*/
- *ATSMB1_SD_STS_2 |= ATSMB_CLK_FREEZ_EN;
- /*Set timer timeout value*/
-
- /*If clock is 390KHz*/
- if (host->current_clock < 400000)
- *ATSMB1_TIMER_VAL = 0x200; /*1024*512*(1/390K) second*/
- else
- *ATSMB1_TIMER_VAL = 0x1fff; /*why not to be 0xffff?*/
-
- /*clear all DMA INT status for safety*/
- *ATSMB1_PDMA_ISR |= SD_PDMA_IER_INT_STS;
-
- /* hook desc */
- *ATSMB1_PDMA_DESPR = host->DescPhyAddr;
- if (config_dir == DMA_CFG_WRITE)
- *ATSMB1_PDMA_CCR &= SD_PDMA_CCR_IF_to_peripheral;
- else
- *ATSMB1_PDMA_CCR |= SD_PDMA_CCR_peripheral_to_IF;
-
- host->DmaIntMask = dma_mask; /*save success event*/
-
- *ATSMB1_PDMA_CCR |= SD_PDMA_CCR_RUN;
- DBG("[%s] e\n",__func__);
-}
-
-/**********************************************************************
-Name : atsmb1_prep_cmd
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static inline void atsmb1_prep_cmd(struct atsmb_host *host,
- u32 opcode,
- u32 arg,
- unsigned int flags,
- u16 blk_len,
- u16 blk_cnt,
- unsigned char int_maks_0,
- unsigned char int_mask_1,
- unsigned char cmd_type,
- unsigned char op)
-{
- DBG("[%s] s\n",__func__);
-
- /*set cmd operation code and arguments.*/
- host->opcode = opcode;
- *ATSMB1_CMD_IDX = opcode; /* host->opcode is set for further use in ISR.*/
- *ATSMB1_CMD_ARG = arg;
-
-#if 0 /* Fixme to support SPI mode, James Tian*/
- if ((flags && MMC_RSP_NONE) == MMC_RSP_NONE)
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R0;
- else if ((flags && MMC_RSP_R1) == MMC_RSP_R1)
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R1;
- else if ((flags && MMC_RSP_R1B) == MMC_RSP_R1B)
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R1b;
- else if ((flags && MMC_RSP_R2) == MMC_RSP_R2)
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R2;
- else if ((flags && MMC_RSP_R3) == MMC_RSP_R3)
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R3;
- else if ((flags && MMC_RSP_R6) == MMC_RSP_R6)
- *ATSMB1_RSP_TYPE = ((opcode != SD_SEND_IF_COND) ? ATMSB_TYPE_R6 : ATMSB_TYPE_R7);
- else
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R0;
-#endif
-
-#if 1
- /*set cmd response type*/
- switch (flags) {
- case MMC_RSP_NONE | MMC_CMD_AC:
- case MMC_RSP_NONE | MMC_CMD_BC:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R0;
- break;
- case MMC_RSP_R1 | MMC_CMD_ADTC:
- case MMC_RSP_R1 | MMC_CMD_AC:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R1;
- break;
- case MMC_RSP_R1B | MMC_CMD_AC:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R1b;
- break;
- case MMC_RSP_R2 | MMC_CMD_BCR:
- case MMC_RSP_R2 | MMC_CMD_AC:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R2;
- break;
- case MMC_RSP_R3 | MMC_CMD_BCR:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R3;
- break;
- case MMC_RSP_R6 | MMC_CMD_BCR: /*MMC_RSP_R6 = MMC_RSP_R7.*/
- *ATSMB1_RSP_TYPE = ((opcode != SD_SEND_IF_COND) ?
- ATMSB_TYPE_R6 : ATMSB_TYPE_R7);
- break;
- case MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC:
- case MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R5;
- break;
- case MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R4;
- break;
- default:
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R0;
- break;
- }
-#endif
- /*SDIO cmd 52 , 53*/
- if ((opcode == SD_IO_RW_DIRECT) ||
- (opcode == SD_IO_RW_EXTENDED)) {
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R5;
- *ATSMB1_RSP_TYPE |= BIT6;
- }
- /*SDIO cmd 5*/
- if ((opcode == SD_IO_SEND_OP_COND) &&
- ((flags & (MMC_RSP_PRESENT|
- MMC_RSP_136|
- MMC_RSP_CRC|
- MMC_RSP_BUSY|
- MMC_RSP_OPCODE)) == MMC_RSP_R4)) {
- *ATSMB1_RSP_TYPE = ATMSB_TYPE_R4;
- *ATSMB1_RSP_TYPE |= BIT6;
- }
-
- /*reset Response FIFO*/
- *ATSMB1_CTL |= 0x08;
-
- /* SD Host enable Clock */
- *ATSMB1_BUS_MODE |= ATSMB_CST;
-
- /*Set Cmd-Rsp Timeout to be maximum value.*/
- *ATSMB1_RSP_TOUT = 0xFE;
-
- /*clear all status registers for safety*/
- *ATSMB1_SD_STS_0 |= 0xff;
- *ATSMB1_SD_STS_1 |= 0xff;
- *ATSMB1_SD_STS_2 |= 0xff;
- //*ATSMB1_SD_STS_2 |= 0x7f;
- *ATSMB1_SD_STS_3 |= 0xff;
-
- //set block length and block count for cmd requesting data
- *ATSMB1_BLK_LEN &=~(0x07ff);
- *ATSMB1_BLK_LEN |= blk_len;
- //*ATSMB1_SHDW_BLKLEN = blk_len;
- *ATSMB1_BLK_CNT = blk_cnt;
-
-
- *ATSMB1_INT_MASK_0 |= int_maks_0;
- *ATSMB1_INT_MASK_1 |= int_mask_1;
-
- //Set Auto stop for Multi-block access
- if(cmd_type == 3 || cmd_type == 4)
- {
- //auto stop command set.
- *ATSMB1_EXT_CTL |= 0x01;
-
-/*
- * Enable transaction abort.
- * When CRC error occurs, CMD 12 would be automatically issued.
- * That is why we cannot enable R/W CRC error INTs.
- * If we enable CRC error INT, we would handle this INT in ISR and then issue CMD 12 via software.
- */
- *ATSMB1_BLK_LEN |= 0x0800;
- }
-
- /*Set read or write*/
- if (op == 1)
- *ATSMB1_CTL &= ~(0x04);
- else if (op == 2)
- *ATSMB1_CTL |= 0x04;
-
- /*for Non data access command, command type is 0.*/
- *ATSMB1_CTL &= 0x0F;
- *ATSMB1_CTL |= (cmd_type<<4);
- DBG("[%s] e\n",__func__);
-}
-
-static inline void atsmb1_issue_cmd(void)
-{
- *ATSMB1_CTL |= ATSMB_START;
- wmb();
-}
-/**********************************************************************
-Name : atsmb1_request_end
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static void
-atsmb1_request_end(struct atsmb_host *host, struct mmc_request *mrq)
-{
- DBG("[%s] s\n",__func__);
- /*
- * Need to drop the host lock here; mmc_request_done may call
- * back into the driver...
- */
- spin_unlock(&host->lock);
- /*DBG("100");*/
- mmc_request_done(host->mmc, mrq);
- /*DBG("101\n");*/
- spin_lock(&host->lock);
- DBG("[%s] e\n",__func__);
-}
-
-/**********************************************************************
-Name : atsmb1_data_done
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-void atsmb1_wait_done(void *data)
-{
- struct atsmb_host *host = (struct atsmb_host *) data;
- DBG("[%s] s\n",__func__);
-
- WARN_ON(host->done_data == NULL);
- complete(host->done_data);
- host->done_data = NULL;
- host->done = NULL;
- DBG("[%s] e\n",__func__);
-}
-
-/**********************************************************************
-Name : atsmb1_start_data
-Function : If we start data, there must be only four cases.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static void atsmb1_start_data(struct atsmb_host *host)
-{
- DECLARE_COMPLETION(complete);
- unsigned char cmd_type = 0;
- unsigned char op = 0; /*0: non-operation; 1:read; 2: write*/
- unsigned char mask_0 = 0;
- unsigned char mask_1 = 0;
- unsigned long dma_mask = 0;
-
- struct mmc_data *data = host->data;
- struct mmc_command *cmd = host->cmd;
-
- struct scatterlist *sg = NULL;
- unsigned int sg_len = 0;
-
- unsigned int total_blks = 0; /*total block number to transfer*/
- u32 card_addr = 0;
- unsigned long dma_len = 0;
- unsigned long total_dma_len = 0;
- dma_addr_t dma_phy = 0; /* physical address used for DMA*/
- unsigned int dma_times = 0; /*times dma need to transfer*/
- unsigned int dma_loop = 0;
- unsigned int sg_num = 0;
- int loop_cnt = 10000;
- unsigned int sg_transfer_len = 0; /*record each time dma transfer sg length */
-
- DBG("[%s] s\n",__func__);
- data->bytes_xfered = 0;
- cmd->error = 0;
- data->error = 0;
-
- /*for loop*/
- sg = data->sg;
- sg_len = data->sg_len;
-
- dma_times = (sg_len / MAX_DESC_NUM);
- if (sg_len % MAX_DESC_NUM)
- dma_times++;
- DBG("dma_times = %d sg_len = %d sg = %x\n", dma_times, sg_len, sg);
- card_addr = cmd->arg; /*may be it is block-addressed, or byte-addressed.*/
- total_blks = data->blocks;
- dma_map_sg(&(host->mmc->class_dev), sg, sg_len,
- ((data->flags)&MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
-
-
- for (dma_loop = 1 ; dma_loop <= dma_times; dma_loop++, sg_len -= sg_transfer_len) {
- DBG("dma_loop = %d sg_len = %d sg_transfer_len = %d\n", dma_loop, sg_len, sg_transfer_len);
- if (dma_loop < dma_times)
- sg_transfer_len = MAX_DESC_NUM;
- else
- sg_transfer_len = sg_len;
- DBG("sg_transfer_len = %d\n", sg_transfer_len);
- /*
- *Firstly, check and wait till card is in the transfer state.
- *For our hardware, we can not consider
- *the card has successfully tranfered its state from data/rcv to trans,
- *when auto stop INT occurs.
- */
- loop_cnt = 10000;
- do {
- if (host->cmd->opcode == SD_IO_RW_EXTENDED)
- break;
- loop_cnt--;
- WARN_ON(loop_cnt == 0);
- host->done_data = &complete;
- host->done = &atsmb1_wait_done;
- host->soft_timeout = 1;
- atsmb1_prep_cmd(host,
- MMC_SEND_STATUS,
- (host->mmc->card->rca)<<16,
- MMC_RSP_R1 | MMC_CMD_AC,
- 0,
- 0,
- 0, /*mask_0*/
- ATSMB_RSP_DONE_EN
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN,
- 0, /*cmd type*/
- 0); /*read or write*/
- atsmb1_issue_cmd();
- DBG("%16s = 0x%8x |", "INT_MASK_1", *ATSMB1_INT_MASK_1);
- DBG("%16s = 0x%8x \n", "SD_STS_1", *ATSMB1_SD_STS_1);
- /*ISR would completes it.*/
- wait_for_completion_timeout(&complete, ATSMB_TIMEOUT_TIME);
-
- WARN_ON(host->soft_timeout == 1);
- if (host->soft_timeout == 1) {
- DBG("%s soft_timeout.\n", __func__);
- atsmb1_dump_reg(host);
- }
- if (cmd->error != MMC_ERR_NONE) {
- cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("Getting Status failed.\n");
- goto end;
- }
- } while ((cmd->resp[0] & 0x1f00) != 0x900 && loop_cnt > 0); /*wait for trans state.*/
-
- /*
- * Now, we can safely issue read/write command.
- * We can not consider this request as multi-block acess or single one via opcode,
- * as request is splitted into sgs.
- * Some sgs may be single one, some sgs may be multi one.
- */
-
- dma_phy = sg_dma_address(sg);
- dma_len = sg_dma_len(sg);
- DBG("dma_len = %d data->blksz = %d sg_len = %d\n", dma_len, data->blksz, sg_len);
- /*SDIO read/write*/
- if (host->cmd->opcode == SD_IO_RW_EXTENDED) {
- /*Single Block read/write*/
- if ((dma_len / (data->blksz)) == 1 && (sg_len == 1)) {
- /* read operation*/
- if (data->flags & MMC_DATA_READ) {
- host->opcode = SD_IO_RW_EXTENDED;
- cmd_type = 2;
- op = 1;
- mask_0 = 0; /*BLOCK_XFER_DONE INT skipped, we use DMA TC INT*/
- mask_1 = (//ATSMB_SDIO_EN
- ATSMB_READ_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = SD_PDMA_CCR_Evt_success;
- DBG("[%s]SR opcode = %d type = 0x%x op = 0x%x m_0 = 0x%x m_1 = 0x%x d_m = 0x%x\n",
- __func__,host->opcode,cmd_type,op,mask_0,mask_1,dma_mask);
- } else {
- /* write operation*/
- host->opcode = SD_IO_RW_EXTENDED;
- cmd_type = 1;
- op = 2;
- /*====That is what we want===== DMA TC INT skipped*/
- mask_0 = ATSMB_BLOCK_XFER_DONE_EN;
- mask_1 = (//ATSMB_SDIO_EN
- ATSMB_WRITE_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = 0;
- DBG("[%s]SW opcode = %d type = 0x%x op = 0x%x m_0 = 0x%x m_1 = 0x%x d_m = 0x%x\n",
- __func__,host->opcode,cmd_type,op,mask_0,mask_1,dma_mask);
- }
- } else {
- /*Multiple Block read/write*/
- /* read operation*/
- if (data->flags & MMC_DATA_READ) {
- host->opcode = SD_IO_RW_EXTENDED;
- cmd_type = 6;
- op = 1;
- mask_0 = 0; /*MULTI_XFER_DONE_EN skipped*/
- mask_1 = (//ATSMB_SDIO_EN /*====That is what we want=====*/
- ATSMB_READ_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = SD_PDMA_CCR_Evt_success;
- DBG("[%s]MR opcode = %d type = 0x%x op = 0x%x m_0 = 0x%x m_1 = 0x%x d_m = 0x%x\n",
- __func__,host->opcode,cmd_type,op,mask_0,mask_1,dma_mask);
- } else {
- /* write operation*/
- host->opcode = SD_IO_RW_EXTENDED;
- cmd_type = 5;
- op = 2;
- mask_0 = ATSMB_MULTI_XFER_DONE_EN;//ATSMB_BLOCK_XFER_DONE_EN; /*MULTI_XFER_DONE INT skipped*/
- mask_1 = (//ATSMB_SDIO_EN /*====That is what we want=====*/
- ATSMB_WRITE_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = 0;
- DBG("[%s]MR opcode = %d type = 0x%x op = 0x%x m_0 = 0x%x m_1 = 0x%x d_m = 0x%x\n",
- __func__,host->opcode,cmd_type,op,mask_0,mask_1,dma_mask);
- }
- }
-
- } else {
- if ((dma_len / (data->blksz)) == 1 && (sg_len == 1)) {
- if (data->flags & MMC_DATA_READ) {/* read operation*/
- host->opcode = MMC_READ_SINGLE_BLOCK;
- cmd_type = 2;
- op = 1;
- mask_0 = 0; /*BLOCK_XFER_DONE INT skipped, we use DMA TC INT*/
- mask_1 = (ATSMB_READ_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = SD_PDMA_CCR_Evt_success;
- } else {/*write operation*/
- host->opcode = MMC_WRITE_BLOCK;
- cmd_type = 1;
- op = 2;
- /*====That is what we want===== DMA TC INT skipped*/
- mask_0 = ATSMB_BLOCK_XFER_DONE_EN;
- mask_1 = (ATSMB_WRITE_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = 0;
- }
- } else { /*more than one*/
- if (data->flags&MMC_DATA_READ) {/* read operation*/
- host->opcode = MMC_READ_MULTIPLE_BLOCK;
- cmd_type = 4;
- op = 1;
- mask_0 = 0; /*MULTI_XFER_DONE_EN skipped*/
- mask_1 = (ATSMB_AUTO_STOP_EN /*====That is what we want=====*/
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = 0;
- } else {/*write operation*/
- host->opcode = MMC_WRITE_MULTIPLE_BLOCK;
- cmd_type = 3;
- op = 2;
- mask_0 = 0; /*MULTI_XFER_DONE INT skipped*/
- mask_1 = (ATSMB_AUTO_STOP_EN /*====That is what we want=====*/
- |ATSMB_DATA_TIMEOUT_EN
- /*Data Timeout and CRC error */
- |ATSMB_RSP_CRC_ERR_EN
- |ATSMB_RSP_TIMEOUT_EN);
- /*Resp Timeout and CRC error */
- dma_mask = 0;
- }
- }
- }
- /*To controller every sg done*/
- host->done_data = &complete;
- host->done = &atsmb1_wait_done;
- /*sleep till ISR wakes us*/
- host->soft_timeout = 1; /*If INT comes early than software timer, it would be cleared.*/
-
- total_dma_len = 0;
- DBG("host->DescVirAddr = %x host->DescSize=%x\n", host->DescVirAddr, host->DescSize);
- memset(host->DescVirAddr, 0, host->DescSize);
- for (sg_num = 0 ; sg_num < sg_transfer_len ; sg++, sg_num++) {
-
- /*
- * Now, we can safely issue read/write command.
- * We can not consider this request as multi-block acess or single one via opcode,
- * as request is splitted into sgs.
- * Some sgs may be single one, some sgs may be multi one.
- */
-
- dma_phy = sg_dma_address(sg);
- dma_len = sg_dma_len(sg);
- total_dma_len = total_dma_len + dma_len;
- DBG("sg_num=%d sg_transfer_len=%d sg=%x sg_len=%d total_dma_len=%d dma_len=%d\n",
- sg_num, sg_transfer_len, sg, sg_len, total_dma_len, dma_len);
- /*2009/01/15 janshiue add*/
- if (sg_num < sg_transfer_len - 1) {
- /* means the last descporitor */
- atsmb1_init_short_desc(
- host->DescVirAddr + (sg_num * sizeof(struct SD_PDMA_DESC_S)/4),
- dma_len, (unsigned long *)dma_phy, 0);
- } else {
- atsmb1_init_short_desc(
- host->DescVirAddr + (sg_num * sizeof(struct SD_PDMA_DESC_S)/4),
- dma_len, (unsigned long *)dma_phy, 1);
- }
- /*2009/01/15 janshiue add*/
-
- }
- /*operate our hardware*/
- atsmb1_prep_cmd(host,
- host->opcode,
- /*arg, may be byte addressed, may be block addressed.*/
- card_addr,
- cmd->flags,
- data->blksz - 1, /* in fact, it is useless.*/
- /* for single one, it is useless. but for multi one, */
- /* it would be used to tell auto stop function whether it is done.*/
- total_dma_len/(data->blksz),
- mask_0,
- mask_1,
- cmd_type,
- op);
-
- atsmb1_config_dma((op == 1) ? DMA_CFG_READ : DMA_CFG_WRITE,
- dma_mask,
- host);
-
- atsmb1_issue_cmd();
- wait_for_completion_timeout(&complete,
- ATSMB_TIMEOUT_TIME*sg_transfer_len); /*ISR would completes it.*/
-
- /* When the address of request plus length equal card bound,
- * force this stop command response as pass. Eason 2012/4/20 */
- if (cmd->resp[0] == 0x80000b00) {
- /*This caes used for SD2.0 and after MMC4.1 version*/
- if (card_addr+(total_dma_len/data->blksz) == host->mmc->card->csd.capacity) {
- cmd->resp[0] = 0x00000b00;
- /*printk("card_addr = %08X, card_length = %08X,card capacity = %08X\n",
- card_addr,(total_dma_len/data->blksz),host->mmc->card->csd.capacity);
- printk("card_resp[0]=%08X, addr = %08X\n",cmd->resp[0],cmd->resp);*/
- }
-
- /* This caes used for SD1.0 and before MMC 4.1 */
- if ((card_addr/data->blksz)+(total_dma_len/data->blksz) == host->mmc->card->csd.capacity) {
- cmd->resp[0] = 0x00000b00;
- /*printk("Eason test: cmd->arg = %08X, data->blksz = %08X, length = %08X\n",
- card_addr,data->blksz,(total_dma_len/data->blksz));*/
- }
- }
-
- if (host->soft_timeout == 1) {
- atsmb1_dump_reg(host);
- //*ATSMB1_BUS_MODE |= ATSMB_SFTRST;
- *ATSMB1_PDMA_GCR = SD_PDMA_GCR_SOFTRESET;
- /*disable INT */
- *ATSMB1_INT_MASK_0 &= ~(ATSMB_BLOCK_XFER_DONE_EN | ATSMB_MULTI_XFER_DONE_EN);
- *ATSMB1_INT_MASK_1 &= ~(ATSMB_WRITE_CRC_ERR_EN|ATSMB_READ_CRC_ERR_EN|ATSMB_RSP_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN|ATSMB_AUTO_STOP_EN|ATSMB_RSP_TIMEOUT_EN|ATSMB_RSP_DONE_EN);
-
- cmd->error = -ETIMEDOUT;
- data->error = -ETIMEDOUT;
- }
-
- WARN_ON(host->soft_timeout == 1);
-
- /*check everything goes okay or not*/
- if (cmd->error != MMC_ERR_NONE
- || data->error != MMC_ERR_NONE) {
- DBG("CMD or Data failed error=%X DescVirAddr=%8X dma_phy=%8X dma_mask = %x\n",
- cmd->error, host->DescVirAddr, dma_phy, host->DmaIntMask);
- goto end;
- }
-// card_addr += total_dma_len>>(mmc_card_blockaddr(host->mmc->card_selected) ? 9 : 0);
- card_addr += total_dma_len>>(mmc_card_blockaddr(host->mmc->card) ? 9 : 0); //zhf: modified by James Tian
- data->bytes_xfered += total_dma_len;
-
-
- }
-// dma_unmap_sg(&(host->mmc->class_dev), data->sg, data->sg_len,
-// ((data->flags)&MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
- WARN_ON(total_blks != (data->bytes_xfered / data->blksz));
- host->opcode = 0;
-end:
- dma_unmap_sg(&(host->mmc->class_dev), data->sg, data->sg_len,
- ((data->flags)&MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
- spin_lock(&host->lock);
- atsmb1_request_end(host, host->mrq);
- spin_unlock(&host->lock);
- DBG("[%s] e\n",__func__);
-}
-
-
-/**********************************************************************
-Name : atsmb1_cmd_with_data_back
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static void atsmb1_cmd_with_data_back(struct atsmb_host *host)
-{
- DECLARE_COMPLETION(complete);
-
- struct scatterlist *sg = NULL;
- unsigned int sg_len = 0;
- DBG("[%s] s\n",__func__);
- /*for loop*/
- sg = host->data->sg;
- sg_len = host->data->sg_len;
- /*To controller every sg done*/
- host->done_data = &complete;
- host->done = &atsmb1_wait_done;
- dma_map_sg(&(host->mmc->class_dev), sg, sg_len, DMA_FROM_DEVICE);
-
- /*2009/01/15 janshiue add*/
- memset(host->DescVirAddr, 0, host->DescSize);
- atsmb1_init_long_desc(host->DescVirAddr, sg_dma_len(sg), (unsigned long *)sg_dma_address(sg), 0, 1);
- /*2009/01/15 janshiue add*/
- /*prepare for cmd*/
- atsmb1_prep_cmd(host, /*host*/
- host->cmd->opcode, /*opcode*/
- host->cmd->arg, /*arg*/
- host->cmd->flags, /*flags*/
- sg_dma_len(sg)-1, /*block length*/
- 0, /*block size: It looks like useless*/
- 0, /*int_mask_0*/
- (ATSMB_RSP_CRC_ERR_EN|ATSMB_RSP_TIMEOUT_EN
- |ATSMB_READ_CRC_ERR_EN |ATSMB_DATA_TIMEOUT_EN), /*int_mask_1*/
- 2, /*cmd_type*/
- 1); /*op*/
-
- atsmb1_config_dma(DMA_CFG_READ,
- SD_PDMA_CCR_Evt_success,
- host);
- atsmb1_issue_cmd();
- /*ISR would completes it.*/
- wait_for_completion_timeout(&complete, ATSMB_TIMEOUT_TIME);
-
- dma_unmap_sg(&(host->mmc->class_dev), host->data->sg, host->data->sg_len,
- ((host->data->flags)&MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
-
- spin_lock(&host->lock);
- atsmb1_request_end(host, host->mrq);
- spin_unlock(&host->lock);
- DBG("[%s] e\n",__func__);
-}
-/**********************************************************************
-Name : atsmb1_start_cmd
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static void atsmb1_start_cmd(struct atsmb_host *host)
-{
- unsigned char int_mask_0,int_mask_1;
- int_mask_0 = 0;
- int_mask_1 = ATSMB_RSP_DONE_EN|ATSMB_RSP_CRC_ERR_EN|ATSMB_RSP_TIMEOUT_EN;
-
- DBG("[%s] s\n",__func__);
-
- atsmb1_prep_cmd(host,
- host->cmd->opcode,
- host->cmd->arg,
- host->cmd->flags,
- 0, /*useless*/
- 0, /*useless*/
- int_mask_0, /*mask_0*/
- int_mask_1, /*mask_1*/
- 0, /*cmd type*/
- 0); /*read or write*/
- atsmb1_issue_cmd();
- DBG("[%s] e\n",__func__);
-}
-/**********************************************************************
-Name : atsmb1_fmt_check_rsp
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static inline void atsmb1_fmt_check_rsp(struct atsmb_host *host)
-{
-
- u8 tmp_resp[4] = {0};
- int i, j, k;
- DBG("[%s] s\n",__func__);
- if (host->cmd->flags != (MMC_RSP_R2 | MMC_CMD_AC)
- && host->cmd->flags != (MMC_RSP_R2 | MMC_CMD_BCR)) {
- for (j = 0, k = 1; j < 4; j++, k++)
- tmp_resp[j] = *(REG8_PTR(_RSP_0 + MMC_ATSMB1_BASE+k));
-
- host->cmd->resp[0] = (tmp_resp[0] << 24) |
- (tmp_resp[1]<<16) | (tmp_resp[2]<<8) | (tmp_resp[3]);
- } else {
- for (i = 0, k = 1; i < 4; i++) { /*R2 has 4 u32 response.*/
- for (j = 0; j < 4; j++) {
- if (k < 16)
- tmp_resp[j] = *(REG8_PTR(_RSP_0 + MMC_ATSMB1_BASE+k));
- else /* k =16*/
- tmp_resp[j] = *(ATSMB1_RSP_0);
- k++;
- }
- host->cmd->resp[i] = (tmp_resp[0]<<24) | (tmp_resp[1]<<16) |
- (tmp_resp[2]<<8) | (tmp_resp[3]);
- }
- }
-
- /*
- * For the situation that we need response,
- * but response registers give us all zeros, we consider this operation timeout.
- */
- if (host->cmd->flags != (MMC_RSP_NONE | MMC_CMD_AC)
- && host->cmd->flags != (MMC_RSP_NONE | MMC_CMD_BC)) {
- if (host->cmd->resp[0] == 0 && host->cmd->resp[1] == 0
- && host->cmd->resp[2] == 0 && host->cmd->resp[3] == 0) {
- host->cmd->error = -ETIMEDOUT; //zhf: modified by James Tian
- }
- }
- DBG("[%s] e\n",__func__);
-}
-/**********************************************************************
-Name : atsmb1_get_slot_status
-Function : Our host only supports one slot.
-Calls :
-Called by :
-Parameter :
-returns : 1: in slot; 0: not in slot.
-Author : Leo Lee
-History :
-***********************************************************************/
-static int atsmb1_get_slot_status(struct mmc_host *mmc)
-{
-// struct atsmb_host *host = mmc_priv(mmc);
- unsigned char status_0 = 0;
-// unsigned long flags;
- unsigned long ret = 0;
- DBG("[%s] s\n",__func__);
-// spin_lock_irqsave(&host->lock, flags); // Vincent Li mark out for CONFIG_PREEMPT_RT
- status_0 = *ATSMB1_SD_STS_0;
-// spin_unlock_irqrestore(&host->lock, flags); // Vincent Li mark out for CONFIG_PREEMPT_RT
- /* after WM3400 A1 ATSMB_CARD_IN_SLOT_GPI = 1 means not in slot*/
- if (MMC1_DRIVER_VERSION >= MMC_DRV_3426_A0) {
- ret = ((status_0 & ATSMB_CARD_NOT_IN_SLOT_GPI) ? 0 : 1);
- DBG("[%s] e1\n",__func__);
- return ret;
- } else {
- ret = ((status_0 & ATSMB_CARD_NOT_IN_SLOT_GPI) ? 1 : 0);
- DBG("[%s] e2\n",__func__);
- return ret;
- }
- DBG("[%s] e3\n",__func__);
- return 0;
-}
-
-/**********************************************************************
-Name : atsmb1_init_short_desc
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Janshiue Wu
-History :
-***********************************************************************/
-int atsmb1_init_short_desc(unsigned long *DescAddr, unsigned int ReqCount, unsigned long *BufferAddr, int End)
-{
- struct SD_PDMA_DESC_S *CurDes_S;
- DBG("[%s] s\n",__func__);
- CurDes_S = (struct SD_PDMA_DESC_S *) DescAddr;
- CurDes_S->ReqCount = ReqCount;
- CurDes_S->i = 0;
- CurDes_S->format = 0;
- CurDes_S->DataBufferAddr = BufferAddr;
- if (End) {
- CurDes_S->end = 1;
- CurDes_S->i = 1;
- }
- DBG("[%s] e\n",__func__);
- return 0;
-}
-
-/**********************************************************************
-Name : atsmb_init_long_desc
-Function :
-Calls :
-Called by :
-Parameter :
-Author : Janshiue Wu
-History :
-***********************************************************************/
-int atsmb1_init_long_desc(unsigned long *DescAddr, unsigned int ReqCount,
- unsigned long *BufferAddr, unsigned long *BranchAddr, int End)
-{
- struct SD_PDMA_DESC_L *CurDes_L;
- DBG("[%s] s\n",__func__);
- CurDes_L = (struct SD_PDMA_DESC_L *) DescAddr;
- CurDes_L->ReqCount = ReqCount;
- CurDes_L->i = 0;
- CurDes_L->format = 1;
- CurDes_L->DataBufferAddr = BufferAddr;
- CurDes_L->BranchAddr = BranchAddr;
- if (End) {
- CurDes_L->end = 1;
- CurDes_L->i = 1;
- }
- DBG("[%s] e\n",__func__);
- return 0;
-}
-
-/**********************************************************************
-Name : atsmb1_dma_isr
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static irqreturn_t atsmb1_dma_isr(int irq, void *dev_id)
-{
-
- struct atsmb_host *host = dev_id;
- u8 status_0, status_1, status_2, status_3;
- u32 pdma_event_code = 0;
- DBG("[%s] s\n",__func__);
-
- disable_irq_nosync(irq);
- spin_lock(&host->lock);
- /*Get INT status*/
- status_0 = *ATSMB1_SD_STS_0;
- status_1 = *ATSMB1_SD_STS_1;
- status_2 = *ATSMB1_SD_STS_2;
- status_3 = *ATSMB1_SD_STS_3;
- /* after WM3426 A0 using PDMA */
- if (MMC1_DRIVER_VERSION >= MMC_DRV_3426_A0) {
-
- pdma_event_code = *ATSMB1_PDMA_CCR & SD_PDMA_CCR_EvtCode;
-
- /* clear INT status to notify HW clear EventCode*/
- *ATSMB1_PDMA_ISR |= SD_PDMA_IER_INT_STS;
-
- /*printk("dma_isr event code = %X\n", *ATSMB1_PDMA_CCR);*/
- /*We expect cmd with data sending back or read single block cmd run here.*/
- if (pdma_event_code == SD_PDMA_CCR_Evt_success) {
- /*means need to update the data->error and cmd->error*/
- if (host->DmaIntMask == SD_PDMA_CCR_Evt_success) {
- if ( host->data != NULL) {
- host->data->error = MMC_ERR_NONE;
- host->cmd->error = MMC_ERR_NONE;
- } else {
- DBG("dma_isr1 host->data is NULL\n");
- /*disable INT*/
- *ATSMB1_PDMA_IER &= ~SD_PDMA_IER_INT_EN;
- goto out;
- }
- }
- /*else do nothing*/
- DBG("dma_isr PDMA OK\n");
- /*atsmb1_dump_reg(host);*/
- }
- /*But unluckily, we should also be prepare for all kinds of error situation.*/
- else {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBGR("** dma_isr PDMA fail** event code = %X\n", *ATSMB1_PDMA_CCR);
- atsmb1_dump_reg(host);
- }
- if (host->DmaIntMask == SD_PDMA_CCR_Evt_success)
- atsmb1_fmt_check_rsp(host);
-
- /*disable INT*/
- *ATSMB1_PDMA_IER &= ~SD_PDMA_IER_INT_EN;
- }
-
- /*wake up some one who is sleeping.*/
- if ((pdma_event_code != SD_PDMA_CCR_Evt_success) || (host->DmaIntMask == SD_PDMA_CCR_Evt_success)) {
- if (host->done_data) {/* We only use done_data when requesting data.*/
- host->soft_timeout = 0;
- host->done(host);
- } else
- atsmb1_request_end(host, host->mrq); /*for cmd with data sending back.*/
- }
-
-out:
- spin_unlock(&host->lock);
- enable_irq(irq);
- DBG("[%s] e\n",__func__);
- return IRQ_HANDLED;
-}
-
-/**********************************************************************
-Name : atsmb1_regular_isr
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-//static irqreturn_t atsmb_regular_isr(int irq, void *dev_id, struct pt_regs *regs)
-irqreturn_t atsmb1_regular_isr(int irq, void *dev_id)
-{
-
- struct atsmb_host *host = dev_id;
- u8 status_0, status_1, status_2, status_3,mask_0,mask_1;
- u32 pdma_sts;
-
- DBG("[%s] s\n",__func__);
- WARN_ON(host == NULL);
-
- disable_irq_nosync(irq);
- spin_lock(&host->lock);
-
- /*Get INT status*/
- status_0 = *ATSMB1_SD_STS_0;
- status_1 = *ATSMB1_SD_STS_1;
- status_2 = *ATSMB1_SD_STS_2;
- status_3 = *ATSMB1_SD_STS_3;
-
- mask_0 = *ATSMB1_INT_MASK_0;
- mask_1 = *ATSMB1_INT_MASK_1;
- /*******************************************************
- card insert interrupt
- ********************************************************/
- if ((status_0 & ATSMB_DEVICE_INSERT) /*Status Set and IRQ enabled*/
- /*To aviod the situation that we intentionally disable IRQ to do rescan.*/
- && (*ATSMB1_INT_MASK_0 & 0x80)) {
-
- if (host->mmc->ops->get_slot_status(host->mmc)) {
- host->mmc->scan_retry = 3;
- host->mmc->card_scan_status = false;
- } else {
- host->mmc->scan_retry = 0;
- host->mmc->card_scan_status = false;
- }
-
- mmc_detect_change(host->mmc, HZ/2);
- /*Taipei Side Request: Disable INSERT IRQ when doing rescan.*/
- //*ATSMB1_INT_MASK_0 &= (~0x80);/* or 40?*/ //zhf: marked by James Tian
- /*Then we clear the INT status*/
- //iowrite32(ATSMB_DEVICE_INSERT, host->base+_SD_STS_0);
- *ATSMB1_SD_STS_0 |= ATSMB_DEVICE_INSERT;
- spin_unlock(&host->lock);
- enable_irq(irq);
- DBG("[%s] e1\n",__func__);
- return IRQ_HANDLED;
- }
-
- if ((status_1 & mask_1)& ATSMB_SDIO_INT) {
- spin_unlock(&host->lock);
- mmc_signal_sdio_irq(host->mmc);
-
- if (((status_1 & mask_1) == ATSMB_SDIO_INT) && ((status_0 & mask_0) == 0)) {
-
- enable_irq(irq);
- DBG("[%s] e2\n",__func__);
-
- return IRQ_HANDLED;
- }
- spin_lock(&host->lock);
- }
- pdma_sts = *ATSMB1_PDMA_CCR;
-
- if (((status_0 & mask_0) | (status_1 & mask_1)) == 0) {
- spin_unlock(&host->lock);
- enable_irq(irq);
- DBG("[%s] e3\n",__func__);
- return IRQ_HANDLED;
- }
- /*******************************************************
- command interrupt.
- *******************************************************/
- /*for write single block*/
- if (host->opcode == MMC_WRITE_BLOCK) {
- if ((status_0 & ATSMB_BLOCK_XFER_DONE)
- && (status_1 & ATSMB_RSP_DONE)) {
- host->data->error = MMC_ERR_NONE;
- host->cmd->error = MMC_ERR_NONE;
- /* okay, what we want.*/
- } else {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err1\n",__func__);
- atsmb1_dump_reg(host);
- }
- } else if (host->opcode == MMC_WRITE_MULTIPLE_BLOCK
- || host->opcode == MMC_READ_MULTIPLE_BLOCK) {
- if ((status_1 & (ATSMB_AUTO_STOP|ATSMB_RSP_DONE))
- && (status_0 & ATSMB_MULTI_XFER_DONE)) {
- /*If CRC error occurs, I think this INT would not occrs.*/
- /*okay, that is what we want.*/
- host->data->error = MMC_ERR_NONE;
- host->cmd->error = MMC_ERR_NONE;
- } else {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err2\n",__func__);
- atsmb1_dump_reg(host);
-
- }
- } else if (host->opcode == MMC_READ_SINGLE_BLOCK) {/* we want DMA TC, run here, must be error.*/
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err3\n",__func__);
- atsmb1_dump_reg(host);
- } else if (host->opcode == SD_IO_RW_EXTENDED){
- /*Write operation*/
- if (*ATSMB1_CTL & BIT2) {
- if ((*ATSMB1_CTL & 0xf0) == 0x10) { /*single block write*/
- if ((status_0 & ATSMB_BLOCK_XFER_DONE)
- && (status_1 & ATSMB_RSP_DONE)) {
- host->data->error = MMC_ERR_NONE;
- host->cmd->error = MMC_ERR_NONE;
- /* okay, what we want.*/
- } else {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err4 status_0 = %x status_1 = %x\n",__func__,status_0,status_1);
- }
-
- } else if ((*ATSMB1_CTL & 0xf0) == 0x50) {
- if ((status_0 & ATSMB_MULTI_XFER_DONE)
- && (status_1 & ATSMB_RSP_DONE)) {
- host->data->error = MMC_ERR_NONE;
- host->cmd->error = MMC_ERR_NONE;
- /* okay, what we want.*/
- } else {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err4-2 status_0 = %x status_1 = %x\n",__func__,status_0,status_1);
- }
- } else {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err4-3 status_0 = %x status_1 = %x\n",__func__,status_0,status_1);
- }
- }
- else {
- /*Read operation*/
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err5\n",__func__);
- }
-
-
- } else {
-/* command, not request data*/
-/* the command which need data sending back,*/
-/* like switch_function, send_ext_csd, send_scr, send_num_wr_blocks.*/
-/* NOTICE: we also send status before reading or writing data, so SEND_STATUS should be excluded.*/
- if (host->data && host->opcode != MMC_SEND_STATUS) {
- host->data->error = -EIO; //MMC_ERR_FAILED;
- host->cmd->error = -EIO; //MMC_ERR_FAILED;
- DBG("[%s] err6\n",__func__);
- atsmb1_dump_reg(host);
- } else { /* Just command, no need data sending back.*/
- if (status_1 & ATSMB_RSP_DONE) {
- /*Firstly, check data-response is busy or not.*/
- if (host->cmd->flags == (MMC_RSP_R1B | MMC_CMD_AC)) {
- int i = 10000;
-
- while (status_2 & ATSMB_RSP_BUSY) {
- status_2 = *ATSMB1_SD_STS_2;
- if (--i == 0)
- break;
- DBG(" IRQ:Status_2 = %d, busy!\n", status_2);
- }
- if (i == 0)
- printk("[MMC driver] Error :SD data-response always busy!");
- }
-#if 1
-/*for our host, even no card in slot, for SEND_STATUS also returns no error.*/
-/*The protocol layer depends on SEND_STATUS to check whether card is in slot or not.*/
-/*In fact, we can also avoid this situation by checking the response whether they are all zeros.*/
- if (!atsmb1_get_slot_status(host->mmc) && host->opcode == MMC_SEND_STATUS) {
- host->cmd->retries = 0; /* No retry.*/
-// host->cmd->error = MMC_ERR_INVALID;
- host->cmd->error = -EINVAL;
- } else
-#endif
- host->cmd->error = MMC_ERR_NONE;
- } else {
- if (status_1 & ATSMB_RSP_TIMEOUT) {/* RSP_Timeout .*/
-// host->cmd->error = MMC_ERR_TIMEOUT;
- host->cmd->error = -ETIMEDOUT;
- DBG("[%s] err7\n",__func__);
- } else {/*or RSP CRC error*/
-// host->cmd->error = MMC_ERR_BADCRC;
- host->cmd->error = -EILSEQ;
- DBG("[%s] err8\n",__func__);
- }
- atsmb1_dump_reg(host);
- }
- }
- }
- atsmb1_fmt_check_rsp(host);
-
- /*disable INT */
- *ATSMB1_INT_MASK_0 &= ~(ATSMB_BLOCK_XFER_DONE_EN | ATSMB_MULTI_XFER_DONE_EN);
- *ATSMB1_INT_MASK_1 &= ~(ATSMB_WRITE_CRC_ERR_EN|ATSMB_READ_CRC_ERR_EN|ATSMB_RSP_CRC_ERR_EN
- |ATSMB_DATA_TIMEOUT_EN|ATSMB_AUTO_STOP_EN|ATSMB_RSP_TIMEOUT_EN|ATSMB_RSP_DONE_EN);
-
-
- /*clear INT status. In fact, we will clear again before issuing new command.*/
- *ATSMB1_SD_STS_0 |= status_0;
- *ATSMB1_SD_STS_1 |= status_1;
-
- /* when read CRC error occur, and the status can't write one to clear.
- * To clear read CRC error status , can do software reset. This is HW bug. 2013/3/21*/
- if ((*ATSMB1_SD_STS_1 & BIT6) == 0x40) {
- DBG("[%s] host1 CMD%d Read CRC error occur\n",__func__,host->cmd->opcode);
- /* Save SD card register */
- atsmb1_copy_reg(0);
- /* Software reset */
- *ATSMB1_BUS_MODE |= BIT7;
- /* restore SD card register */
- atsmb1_copy_reg(1);
- }
-
- if (*ATSMB1_PDMA_ISR & SD_PDMA_IER_INT_STS)
- *ATSMB1_PDMA_ISR |= SD_PDMA_IER_INT_STS;
-
- /*wake up some one who is sleeping.*/
- if (host->done_data) { /* We only use done_data when requesting data.*/
- host->soft_timeout = 0;
- host->done(host);
- } else
- atsmb1_request_end(host, host->mrq); /*for cmd without data.*/
-
- spin_unlock(&host->lock);
- enable_irq(irq);
- DBG("[%s] e4\n",__func__);
- return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(atsmb1_regular_isr);
-
-/**********************************************************************
-Name : atsmb1_get_ro
-Function :.
-Calls :
-Called by :
-Parameter :
-returns : 0 : write protection is disabled. 1: write protection is enabled.
-Author : Leo Lee
-History :
-***********************************************************************/
-int atsmb1_get_ro(struct mmc_host *mmc)
-{
- struct atsmb_host *host = mmc_priv(mmc);
- unsigned char status_0 = 0;
- unsigned long flags;
- unsigned long ret = 0;
- DBG("[%s] s\n",__func__);
- spin_lock_irqsave(&host->lock, flags);
- status_0 = *ATSMB1_SD_STS_0;
- spin_unlock_irqrestore(&host->lock, flags);
- DBG("[%s]\nstatus_0 = 0x%x\n", __func__,status_0);
- ret = ((status_0 & ATSMB_WRITE_PROTECT) ? 0 : 1);
- DBG("[%s] e\n",__func__);
- return ret;
-}
-/**********************************************************************
-Name : atsmb1_dump_host_regs
-Function :
-Calls :
-Called by :
-Parameter :
-returns :
-Author : Leo Lee
-History :
-***********************************************************************/
-void atsmb1_dump_host_regs(struct mmc_host *mmc)
-{
- struct atsmb_host *host = mmc_priv(mmc);
- DBG("[%s] s\n",__func__);
- atsmb1_dump_reg(host);
- DBG("[%s] e\n",__func__);
-}
-EXPORT_SYMBOL(atsmb1_dump_host_regs);
-
-/**********************************************************************
-Name : atsmb_enable_sdio_irq
-Function :
-Calls :
-Called by :
-Parameter :
-returns :
-Author : Tommy Huang
-History :
-***********************************************************************/
-static void atsmb1_enable_sdio_irq(struct mmc_host *mmc, int enable)
-{
- struct atsmb_host *host = mmc_priv(mmc);
- unsigned long flags;
-
- DBG("[%s] s enable = %d *ATSMB1_INT_MASK_1 = %x\n",__func__,enable,*ATSMB1_INT_MASK_1);
- spin_lock_irqsave(&host->lock, flags);
-
- if (enable) {
- *ATSMB1_INT_MASK_1 |= ATSMB_SDIO_EN;
- } else {
- *ATSMB1_INT_MASK_1 &= ~ATSMB_SDIO_EN;
- }
-
- spin_unlock_irqrestore(&host->lock, flags);
- DBG("[%s] e\n",__func__);
-
-}
-/**********************************************************************
-Name : atsmb_request
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static void atsmb1_request(struct mmc_host *mmc, struct mmc_request *mrq)
-{
-
- struct atsmb_host *host = mmc_priv(mmc);
- DBG("[%s] s\n",__func__);
-
- /* May retry process comes here.*/
- host->mrq = mrq;
- host->data = mrq->data;
- host->cmd = mrq->cmd;
- host->done_data = NULL;
- host->done = NULL;
-
- /*for data request*/
- if (host->data) {
- if (host->cmd->opcode == MMC_WRITE_BLOCK
- || host->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK
- || host->cmd->opcode == MMC_READ_SINGLE_BLOCK
- || host->cmd->opcode == MMC_READ_MULTIPLE_BLOCK
- || host->cmd->opcode == SD_IO_RW_EXTENDED) {
- atsmb1_start_data(host);
- } else {
- atsmb1_cmd_with_data_back(host);
- }
- } else {
- atsmb1_start_cmd(host);
- }
- DBG("[%s] e\n",__func__);
-}
-/**********************************************************************
-Name : atsmb1_set_clock
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Eason Chien
-History :2012/7/19
-***********************************************************************/
-static int atsmb1_set_clock(struct mmc_host *mmc, unsigned int clock)
-{
- int clock_multiplier = 1;
- DBG("clock = %u\n",clock);
-
- if (*ATSMB1_EXT_BUS_MODE & BIT4) /*Enable DDR50*/
- clock_multiplier = 2;
-
- if (clock == mmc->f_min) {
- DBG("[%s]ATSMB1 Host 400KHz\n", __func__);
- return auto_pll_divisor(DEV_SDMMC1, SET_DIV, 1, 390 * clock_multiplier);
- } else if (clock >= 50000000) {
- DBG("[%s]ATSMB1 Host 50MHz\n", __func__);
- return auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 45 * clock_multiplier);
- } else if ((clock >= 25000000) && (clock < 50000000)) {
- DBG("[%s]ATSMB1 Host 25MHz\n", __func__);
- return auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 24 * clock_multiplier);
- } else if ((clock >= 20000000) && (clock < 25000000)) {
- DBG("[%s]ATSMB1 Host 20MHz\n", __func__);
- return auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 20 * clock_multiplier);
- } else {
- DBG("[%s]ATSMB1 Host 390KHz\n", __func__);
- return auto_pll_divisor(DEV_SDMMC1, SET_DIV, 1, 390 * clock_multiplier);
- }
-}
-
-/**********************************************************************
-Name : atsmb1_set_ios
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static void atsmb1_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-{
-
- struct atsmb_host *host = mmc_priv(mmc);
- unsigned long flags;
- unsigned int strapping;
-
- DBG("[%s] s\n",__func__);
- spin_lock_irqsave(&host->lock, flags);
-
- if (ios->power_mode == MMC_POWER_OFF) {
- if (MMC1_DRIVER_VERSION == MMC_DRV_3498) {
- if (atsmb1_first_boot) {
- /*nothing to do for GPIO setting when first boot.*/
- } else {
- /* stop SD output clock */
- *ATSMB1_BUS_MODE &= ~(ATSMB_CST);
-
- /* disable SD1 Card power */
- /*set SD1 power pin as GPO pin*/
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL |= GPIO_SD1_POWER;
- GPIO_OC_GP14_NAND_SD1_BYTE_VAL |= GPIO_SD1_POWER;
- /*set internal pull up*/
- PULL_CTRL_GP14_NAND_BYTE_VAL |= GPIO_SD1_POWER;
- /*set internal pull enable*/
- PULL_EN_GP14_NAND_BYTE_VAL |= GPIO_SD1_POWER;
- /*disable SD1 power*/
- GPIO_OD_GP14_NAND_SD1_BYTE_VAL |= GPIO_SD1_POWER;
-
- /* Config SD1 to GPIO */
- GPIO_CTRL_GP16_NAND_SD1_BYTE_VAL |= GPIO_SD1_Data;
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL |= SD1_PIN;
-
- /* SD1 all pins output low */
- GPIO_OD_GP16_NAND_SD1_BYTE_VAL &= ~GPIO_SD1_Data;
- GPIO_OD_GP14_NAND_SD1_BYTE_VAL &= ~SD1_PIN;
-
- /* Config SD1 to GPIO */
- GPIO_OC_GP16_NAND_SD1_BYTE_VAL |= GPIO_SD1_Data;
- GPIO_OC_GP14_NAND_SD1_BYTE_VAL |= SD1_PIN;
-
- /*Set SD1 CMD pin pull low because SD1CMD has no gpio pin, check with Jim*/
- /*PULL_CTRL_GP14_NAND_BYTE_VAL &= ~GPIO_SD1_Command;
- PULL_EN_GP14_NAND_BYTE_VAL |= GPIO_SD1_Command;*/
- }
- }
- } else if (ios->power_mode == MMC_POWER_UP) {
- if (MMC1_DRIVER_VERSION == MMC_DRV_3498) {
- if (atsmb1_first_boot) {
- /*nothing to do for GPIO setting when first boot.*/
- } else {
- /* disable SD Card power */
- /*set SD1 power pin as GPO pin*/
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL |= GPIO_SD1_POWER;
- GPIO_OC_GP14_NAND_SD1_BYTE_VAL |= GPIO_SD1_POWER;
- /*set internal pull up*/
- PULL_CTRL_GP14_NAND_BYTE_VAL |= GPIO_SD1_POWER;
- /*set internal pull enable*/
- PULL_EN_GP14_NAND_BYTE_VAL |= GPIO_SD1_POWER;
- /*disable SD1 power*/
- GPIO_OD_GP14_NAND_SD1_BYTE_VAL |= GPIO_SD1_POWER;
-
- /* enable SD1 PIN share */
- PIN_SHARING_SEL_4BYTE_VAL |= GPIO_SD1_PinShare;
-
- /* do not config GPIO_SD1_CD because ISR has already run,
- * config card detect will issue ISR storm.
- */
- /* Config SD to GPIO */
- GPIO_CTRL_GP16_NAND_SD1_BYTE_VAL |= GPIO_SD1_Data;
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL |= SD1_PIN;
-
- /* SD all pins output low */
- GPIO_OD_GP16_NAND_SD1_BYTE_VAL &= ~GPIO_SD1_Data;
- GPIO_OD_GP14_NAND_SD1_BYTE_VAL &= ~SD1_PIN;
-
- /* Config SD to GPO */
- GPIO_OC_GP16_NAND_SD1_BYTE_VAL |= GPIO_SD1_Data;
- GPIO_OC_GP14_NAND_SD1_BYTE_VAL |= SD1_PIN;
-
- /* stop SD output clock */
- *ATSMB1_BUS_MODE &= ~ATSMB_CST;
-
- /* Pull up/down resister of SD Bus */
- /*Disable Clock & CMD Pull enable*/
- PULL_EN_GP14_NAND_BYTE_VAL &= ~(GPIO_SD1_Clock | GPIO_SD1_Command);
-
- /*Set CD ,WP ,DATA pin pull up*/
- PULL_CTRL_GP16_NANDIO_BYTE_VAL |= GPIO_SD1_Data;
- PULL_CTRL_GP14_NAND_BYTE_VAL |= (GPIO_SD1_WriteProtect | GPIO_SD1_CD);
-
- /*Enable CD ,WP ,DATA internal pull*/
- PULL_EN_GP16_NANDIO_BYTE_VAL |= GPIO_SD1_Data;
- PULL_EN_GP14_NAND_BYTE_VAL |= (GPIO_SD1_WriteProtect | GPIO_SD1_CD);
-
- spin_unlock_irqrestore(&host->lock, flags);
- msleep(1);
- spin_lock_irqsave(&host->lock, flags);
-
- /* enable SD1 power */
- GPIO_OD_GP14_NAND_SD1_BYTE_VAL &= ~GPIO_SD1_POWER;
-
- /* enable SD output clock */
- *ATSMB1_BUS_MODE |= ATSMB_CST;
-
- spin_unlock_irqrestore(&host->lock, flags);
- msleep(1);
- spin_lock_irqsave(&host->lock, flags);
-
- /* Config SD1 back to function */
- GPIO_CTRL_GP16_NAND_SD1_BYTE_VAL &= ~GPIO_SD1_Data;
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL &= ~SD1_PIN;
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL &= ~GPIO_SD1_CD;
-
- /* terminate emmc boot mode */
- DBG("[%s] STRAP_STATUS_VAL = 0x%x\n", __func__, STRAP_STATUS_VAL);
- strapping = STRAP_STATUS_VAL & 0xE;
- if (strapping == 0x2) {
- printk("[%s] strapping = 0x%x, terminate boot mode\n", __func__, strapping);
- *ATSMB1_EXT_BUS_MODE &= ~BIT0;
- *ATSMB1_BUS_MODE &= ~BIT4;
- *ATSMB1_BUS_MODE |= BIT4;
- }
- }
- }
- } else {
- /*nothing to do when powering on.*/
- }
-
- host->current_clock = atsmb1_set_clock(mmc,ios->clock);
-
- if (ios->bus_width == MMC_BUS_WIDTH_8) {
- *ATSMB1_EXT_CTL |= (0x04);
- } else if (ios->bus_width == MMC_BUS_WIDTH_4) {
- *ATSMB1_BUS_MODE |= ATSMB_BUS_WIDTH_4;
- *ATSMB1_EXT_CTL &= ~(0x04);
- } else {
- *ATSMB1_BUS_MODE &= ~(ATSMB_BUS_WIDTH_4);
- *ATSMB1_EXT_CTL &= ~(0x04);
- }
-
-#if 1
- if (ios->timing == MMC_TIMING_SD_HS)
- *ATSMB1_EXT_CTL &= ~0x80; /*HIGH SPEED MODE hsot1 H_S must be off for wm3498*/
- else if (ios->timing == MMC_TIMING_MMC_HS)
- *ATSMB1_EXT_CTL &= ~0x80;
- else if (ios->timing == MMC_TIMING_UHS_DDR50) {
- /* enable emmc DDR mode */
- *ATSMB1_EXT_BUS_MODE |= BIT4; /*Enable DDR50*/
- /* enable SD output clock */
- *ATSMB1_BUS_MODE &= ~ATSMB_CST;
- spin_unlock_irqrestore(&host->lock, flags);
- msleep(1);
- spin_lock_irqsave(&host->lock, flags);
-
- *ATSMB1_EXT_BUS_MODE |= BIT4; /*Enable DDR50*/
- /* enable SD output clock */
- *ATSMB0_BUS_MODE |= ATSMB_CST;
- /*BIT4~7: PMOS driver strength, BIT8~11: NMOS driver strength */
- DRV_SPI_NAND_4BYTE_VAL |= (BIT4 |BIT5 | BIT6 | BIT7 | BIT8 | BIT9 | BIT10 | BIT11);
- }
-#endif
-#if 0 //zhf: marked by James Tian
- if (ios->ins_en == MMC_INSERT_IRQ_EN)
- *ATSMB1_INT_MASK_0 |= (0x80);/* or 40?*/
- else
- *ATSMB1_INT_MASK_0 &= (~0x80);/* or 40?*/
-#endif
-
- spin_unlock_irqrestore(&host->lock, flags);
- DBG("[%s] e\n",__func__);
-}
-
-
-static const struct mmc_host_ops atsmb1_ops = {
- .request = atsmb1_request,
- .set_ios = atsmb1_set_ios,
- .get_ro = atsmb1_get_ro,
- .get_slot_status = atsmb1_get_slot_status,
- .dump_host_regs = atsmb1_dump_host_regs,
- .enable_sdio_irq = atsmb1_enable_sdio_irq,
-};
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-/**********************************************************************
-Name :atsmb1_probe
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static int __init atsmb1_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mmc_host *mmc_host = NULL;
- struct atsmb_host *atsmb_host = NULL;
- struct resource *resource = NULL;
- int irq[2] = {0};
- int ret = 0;
- DBG("[%s] s\n",__func__);
- if (!pdev) {
- ret = -EINVAL; /* Invalid argument */
- goto the_end;
- }
-
-
- /*Enable SD host clock*/
- auto_pll_divisor(DEV_SDMMC1, CLK_ENABLE, 0, 0);
-
- if (MMC1_DRIVER_VERSION == MMC_DRV_3498) {
- /* enable SD1 PIN share */
- PIN_SHARING_SEL_4BYTE_VAL |= GPIO_SD1_PinShare;
-
- /* Pull up/down resister of SD CD */
- PULL_CTRL_GP14_NAND_BYTE_VAL |= GPIO_SD1_CD;
- PULL_EN_GP14_NAND_BYTE_VAL |= GPIO_SD1_CD;
-
- /* config CardDetect pin to SD function */
- GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL &= ~GPIO_SD1_CD;
- }
-
- /* support emmc fisrt boot don't setting GPIO*/
- atsmb1_first_boot = 1; //1:first boot, 0: suspend/resume
-
- resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!resource) {
- ret = -ENXIO; /* No such device or address */
- printk(KERN_ALERT "[MMC/SD driver] Getting platform resources failed!\n");
- goto the_end;
- }
-#if 0
- if (!request_mem_region(resource->start, SZ_1K, MMC1_DRIVER_NAME)) {
- ret = -EBUSY;
- printk(KERN_ALERT "[MMC/SD driver] Request memory region failed!\n");
- goto the_end ;
- }
-#endif
- irq[0] = platform_get_irq(pdev, 0); /*get IRQ for device*/;
- irq[1] = platform_get_irq(pdev, 1); /*get IRQ for dma*/;
-
- if (irq[0] == NO_IRQ || irq[1] == NO_IRQ) {
- ret = -ENXIO;/* No such device or address */
- printk(KERN_ALERT "[MMC/SD driver] Get platform IRQ failed!\n");
- goto rls_region;
- }
-
- /*allocate a standard msp_host structure attached with a atsmb structure*/
- mmc_host = mmc_alloc_host(sizeof(struct atsmb_host), dev);
- if (!mmc_host) {
- ret = -ENOMEM;
- printk(KERN_ALERT "[MMC/SD driver] Allocating driver's data failed!\n");
- goto rls_region;
- }
- mmc_host->wmt_host_index = 1; /*to identify host number*/
-
- dev_set_drvdata(dev, (void *)mmc_host); /* mmc_host is driver data for the atsmb dev.*/
- atsmb_host = mmc_priv(mmc_host);
-
- mmc_host->ops = &atsmb1_ops;
-
- mmc_host->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
-
- mmc_host->f_min = 390425; /*390.425Hz = 400MHz/64/16*/
- mmc_host->f_max = 50000000; /* in fact, the max frequency is 400MHz( = 400MHz/1/1)*/
-
- if (SDXC1_function == 1) {
- mmc_host->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ
- | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50;
- } else if (SDXC1_function == 0) {
- mmc_host->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ
- | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_8_BIT_DATA; /* */ //zhf: marked by James Tian
- }
-
- mmc_host->max_segs = 128; /*we use software sg. so we could manage even larger number.*/
-
- /*1MB per each request */
- /*we have a 16 bit block number register, and block length is 512 bytes.*/
- mmc_host->max_req_size = 16*512*(mmc_host->max_segs);
- mmc_host->max_seg_size = 65024; /* 0x7F*512 PDMA one descriptor can transfer 64K-1 byte*/
- mmc_host->max_blk_size = 2048; /* our block length register is 11 bits.*/
- mmc_host->max_blk_count = (mmc_host->max_req_size)/512;
-
- /*set the specified host -- ATSMB*/
-#ifdef CONFIG_MMC_UNSAFE_RESUME
- mmc_host->card_attath_status = card_attach_status_unchange;
-#endif
- sema_init(&mmc_host->req_sema,1); /*initial request semaphore*/
-#if 0
- atsmb_host->base = ioremap(resource->start, SZ_1K);
- if (!atsmb_host->base) {
- printk(KERN_ALERT "[MMC/SD driver] IO remap failed!\n");
- ret = -ENOMEM;
- goto fr_host;
- }
-#endif
- atsmb_host->base = (void *)resource->start;
- atsmb_host->mmc = mmc_host;
- spin_lock_init(&atsmb_host->lock);
- atsmb_host->res = resource;/* for atsmb_remove*/
-
- /*disable all interrupt and clear status by resetting controller.*/
- //*ATSMB1_BUS_MODE |= ATSMB_SFTRST; //emmc card don't execute SW reset. because uboot is done.
- *ATSMB1_BLK_LEN &= ~(0xa000);
- *ATSMB1_SD_STS_0 |= 0xff;
- *ATSMB1_SD_STS_1 |= 0xff;
-
- /* WM3437 A0 default not output clock, after SFTRST need to enable SD clock */
- //if (MMC1_DRIVER_VERSION >= MMC_DRV_3437_A0) /* including 3429 */
- *ATSMB1_BUS_MODE |= ATSMB_CST;
-
- atsmb_host->regular_irq = irq[0];
- atsmb_host->dma_irq = irq[1];
-
- ret = request_irq(atsmb_host->regular_irq,
- atsmb1_regular_isr,
- IRQF_SHARED, //SA_SHIRQ, /*SA_INTERRUPT, * that is okay?*/ //zhf: modified by James Tian, should be IRQF_SHARED?
- MMC1_DRIVER_NAME,
- (void *)atsmb_host);
- if (ret) {
- printk(KERN_ALERT "[MMC/SD driver] Failed to register regular ISR!\n");
- goto unmap;
- }
-
- ret = request_irq(atsmb_host->dma_irq,
- atsmb1_dma_isr,
- IRQF_DISABLED, // SA_INTERRUPT, //zhf: modified by James Tian
- MMC1_DRIVER_NAME,
- (void *)atsmb_host);
- if (ret) {
- printk(KERN_ALERT "[MMC/SD driver] Failed to register DMA ISR!\n");
- goto fr_regular_isr;
- }
-
-
-
- /*wait card detect status change*/
- //msleep(10);
- /*enable card insertion interrupt and enable DMA and its Global INT*/
- *ATSMB1_BLK_LEN |= (0xa000); /* also, we enable GPIO to detect card.*/
- *ATSMB1_SD_STS_0 |= 0xff;
- *ATSMB1_INT_MASK_0 |= 0x80; /*or 0x40?*/
-
- /*allocation dma descriptor*/
- ret = atsmb1_alloc_desc(atsmb_host, sizeof(struct SD_PDMA_DESC_S) * MAX_DESC_NUM);
- if (ret == -1) {
- printk(KERN_ALERT "[MMC/SD driver] Failed to allocate DMA descriptor!\n");
- goto fr_dma_isr;
- }
- printk(KERN_INFO "WMT ATSMB1 (AHB To SD/MMC1 Bus) controller registered!\n");
- mmc_add_host(mmc_host,true);
-
- DBG("[%s] e1\n",__func__);
- return 0;
-
-fr_dma_isr:
- free_irq(atsmb_host->dma_irq, atsmb_host);
-fr_regular_isr:
- free_irq(atsmb_host->regular_irq, atsmb_host);
-unmap:
- //iounmap(atsmb_host->base);
-//fr_host:
- dev_set_drvdata(dev, NULL);
- mmc_free_host(mmc_host);
-rls_region:
- //release_mem_region(resource->start, SZ_1K);
-the_end:
- printk(KERN_ALERT "[MMC/SD driver] ATSMB1 probe Failed!\n") ;
- DBG("[%s] e2\n",__func__);
- return ret;
-}
-/**********************************************************************
-Name : atsmb1_remove
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static int atsmb1_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mmc_host *mmc_host = (struct mmc_host *)dev_get_drvdata(dev);
- struct atsmb_host *atsmb_host;
-
- DBG("[%s] s\n",__func__);
- atsmb_host = mmc_priv(mmc_host);
- if (!mmc_host || !atsmb_host) {
- printk(KERN_ALERT "[MMC/SD driver] ATSMB1 remove method failed!\n");
- DBG("[%s] e1\n",__func__);
- return -ENXIO;
- }
- mmc_remove_host(mmc_host);
-
- /*disable interrupt by resetting controller -- for safey*/
- *ATSMB1_BUS_MODE |= ATSMB_SFTRST;
- *ATSMB1_BLK_LEN &= ~(0xa000);
- *ATSMB1_SD_STS_0 |= 0xff;
- *ATSMB1_SD_STS_1 |= 0xff;
-
- (void)free_irq(atsmb_host->regular_irq, atsmb_host);
- (void)free_irq(atsmb_host->dma_irq, atsmb_host);
- (void)iounmap(atsmb_host->base);
- (void)release_mem_region(atsmb_host->res->start, SZ_1K);
- dev_set_drvdata(dev, NULL);
- /*free dma descriptor*/
- dma_free_coherent(atsmb_host->mmc->parent, atsmb_host->DescSize,
- atsmb_host->DescVirAddr, atsmb_host->DescPhyAddr);
- (void)mmc_free_host(mmc_host);/* also free atsmb_host.*/
- DBG("[%s] e2\n",__func__);
- return 0;
-}
-
-/**********************************************************************
-Name : atsmb_shutdown
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Tommy Huang
-History :
-***********************************************************************/
-static void atsmb1_shutdown(struct platform_device *pdev)
-{
- /*atsmb1_shutdown don't be used now.*/
- /*struct device *dev = &pdev->dev;
- struct mmc_host *mmc_host = (struct mmc_host *)dev_get_drvdata(dev);*/
-
- DBG("[%s] s\n",__func__);
-
- /* turn off clock before emmc card shutdown. */
- *ATSMB1_BUS_MODE &= ~(ATSMB_CST);
-
- /*Disable card detect interrupt*/
- *ATSMB1_INT_MASK_0 &= ~0x80;
- DBG("[%s] e\n",__func__);
-
-}
-
-/**********************************************************************
-Name : atsmb_suspend
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-#ifdef CONFIG_PM
-static int atsmb1_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct device *dev = &pdev->dev;
- struct mmc_host *mmc = (struct mmc_host *)dev_get_drvdata(dev);
- int ret = 0;
- DBG("[%s] s\n",__func__);
-
- /* after suspend/resume, it isn't first boot*/
- atsmb1_first_boot = 0;
-
- if (mmc) {
- /*struct atsmb_host *host = mmc_priv(mmc);*/
- ret = mmc_suspend_host(mmc);
- if (ret == 0) {
- /*disable all interrupt and clear status by resetting controller. */
- *ATSMB1_BUS_MODE |= ATSMB_SFTRST;
- *ATSMB1_BLK_LEN &= ~(0xa000);
- *ATSMB1_SD_STS_0 |= 0xff;
- *ATSMB1_SD_STS_1 |= 0xff;
-
- }
- /*disable source clock*/
- //TODO: SD1 clock en or dis
- auto_pll_divisor(DEV_SDMMC1, CLK_DISABLE, 0, 0);
-#ifdef CONFIG_MMC_UNSAFE_RESUME
- /*clean SD card attatch status change*/
- PMCWS_VAL |= BIT20;
- mmc->card_attath_status = card_attach_status_unchange;
-#endif
- }
-
- DBG("[%s] e\n",__func__);
- return ret;
-}
-/**********************************************************************
-Name : atsmb_resume
-Function :.
-Calls :
-Called by :
-Parameter :
-Author : Leo Lee
-History :
-***********************************************************************/
-static int atsmb1_resume(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mmc_host *mmc = (struct mmc_host *)dev_get_drvdata(dev);
- int ret = 0;
- DBG("[%s] s\n",__func__);
-
- /*
- * enable interrupt, DMA, etc.
- * Supply power to slot.
- */
- if (mmc) {
- /*enable source clock*/
- auto_pll_divisor(DEV_SDMMC1, CLK_ENABLE, 0, 0);
-
- udelay(1);
- /*enable card insertion interrupt and enable DMA and its Global INT*/
- *ATSMB1_BUS_MODE |= ATSMB_SFTRST;
- *ATSMB1_BLK_LEN |= (0xa000);
- *ATSMB1_INT_MASK_0 |= 0x80; /* or 40?*/
-#ifdef CONFIG_MMC_UNSAFE_RESUME
- /*modify SD card attatch status change*/
- if ((PMCWS_VAL & BIT20) && !mmc->bus_dead) {
- /*card change when suspend mode*/
- mmc->card_attath_status = card_attach_status_change;
- /*clean SD card attatch status change*/
- PMCWS_VAL |= BIT20;
- }
-#endif
- ret = mmc_resume_host(mmc);
- }
-
- DBG("[%s] e\n",__func__);
- return ret;
-}
-#else
-#define atsmb1_suspend NULL
-#define atsmb1_resume NULL
-#endif
-
-static struct platform_driver atsmb1_driver = {
- .driver.name = "sdmmc1",
- //.probe = atsmb1_probe,
- .remove = atsmb1_remove,
- .shutdown = atsmb1_shutdown,
- .suspend = atsmb1_suspend,
- .resume = atsmb1_resume,
-};
-
-static struct platform_device wmt_sdmmc1_device = {
- .name = "sdmmc1",
- .id = 0,
- .dev = {
- .dma_mask = &wmt_sdmmc1_dma_mask,
- .coherent_dma_mask = ~0,
- .release = atsmb1_release,
- },
- .num_resources = ARRAY_SIZE(wmt_sdmmc1_resources),
- .resource = wmt_sdmmc1_resources,
-};
-
-
-static int __init atsmb1_init(void)
-{
- int ret;
- int retval;
- unsigned char buf[80];
- int varlen = 80;
- char *varname = "wmt.sd1.param";
- int temp = 0, sd_enable = 0; /*0 :disable 1:enable*/
-
- DBG("[%s] s\n",__func__);
-
-#ifdef CONFIG_MTD_WMT_SF
- /*Read system param to identify host function 0: SD/MMC 1:SDIO wifi*/
- retval = wmt_getsyspara(varname, buf, &varlen);
- if (retval == 0) {
- sscanf(buf,"%x:%d", &temp, &SD1_function);
- printk(KERN_ALERT "wmt.sd1.param = %x:%d\n", temp, SD1_function);
- sd_enable = temp & 0xf;
- SDXC1_function = (temp >> 4) & 0xf;
- printk(KERN_ALERT "SD1 ebable = %x, SDXC = %x, function = %x\n",
- sd_enable, SDXC1_function, SD1_function);
-
- if (SD1_function < 0 || SD1_function >= SD_MAX_FUN)
- return -ENODEV;
- } else {
- printk(KERN_ALERT "Default wmt.sd1.param = %x:%d\n", temp, SD1_function);
- }
-#endif
- /*SD function disable*/
- if (sd_enable != 1)
- return -ENODEV;
-
- get_driver_version1();
-
- if (platform_device_register(&wmt_sdmmc1_device))//add by jay,for modules support
- return -1;
- //ret = platform_driver_register(&atsmb1_driver);
- ret = platform_driver_probe(&atsmb1_driver, atsmb1_probe);
-
- DBG("[%s] e\n",__func__);
- return ret;
-}
-
-static void __exit atsmb1_exit(void)
-{
- DBG("[%s] s\n",__func__);
- (void)platform_driver_unregister(&atsmb1_driver);
- (void)platform_device_unregister(&wmt_sdmmc1_device);//add by jay,for modules support
- DBG("[%s] e\n",__func__);
-}
-
-module_init(atsmb1_init);
-module_exit(atsmb1_exit);
-module_param(fmax1, uint, 0444);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT [AHB to SD/MMC1 Bridge] driver");
-MODULE_LICENSE("GPL");