移植Motorola开源的SD/MMC驱动程序

2019-07-13 02:16发布

移植Motorola开源的SD/MMC驱动程序

首先感谢Motorola的开源精神,它告诉其他嵌入式linux的开发人员:你们不是一个人在战斗,不是一个人!

好了,言归正传,下面将介绍我的移植过程。

内核版本为linux-2.4.21,CPU是PXA255。

下载
motorola开源的SM/MM驱动程序源码
https://opensource.motorola.com/sf/frs/do/listReleases/projects.sd-mmc/frs.sample_package
解压该源码包,有driver和include两个目录,分别复制到内核相应的目录下。

修改Makefile和Config.in文件,可参考E680的设置。

下面是主要源码文件的修改过程:

添加文件include/asm-arm/arch-pxa/ezx.h
#define GPIO_MMC_DETECT 12                    测试卡是否存在
#define GPIO_MMC_CLK    6       
#define GPIO_MMC_WP     26                    写保护
#define GPIO_MMC_MMCCS0 8

修改include/asm-arm/arch-pxa/pxa-regs.h
添加宏
/*
 * MultiMediaCard (MMC) controller
 */

#define MMC_STRPCL      __REG(0x41100000)       /* Control to start and stop MMC clock */
#define MMC_STRPCL_STRT_CLK     (1 << 1)        /* Start the MMC clock */
#define MMC_STRPCL_STOP_CLK     (1 << 0)        /* Stop the MMC clock */
#define MMC_STAT        __REG(0x41100004)       /* MMC Status Register (read only) */
#define MMC_STAT_SDIO_SUSPEND_ACK (1 << 16)     /* SDIO data transfer has been
                                                   suspended by SDIO card */
#define MMC_STAT_SDIO_INT       (1 << 15)       /* SDIO Interrupt occured */
#define MMC_STAT_RD_STALLED     (1 << 14)       /* Read transfer stalled */
#define MMC_STAT_END_CMD_RES    (1 << 13)       /* Command and response
                                                   sequence has completed */
#define MMC_STAT_PRG_DONE       (1 << 12)       /* Card has finished programming
                                                   and is not busy */
#define MMC_STAT_DATA_TRAN_DONE (1 << 11)       /* Data transmission to card
                                                   has been completed */
#define MMC_STAT_SPI_WR_ERR     (1 << 10)       /* Write data rejected by card
                                                   due to a Write Error */
#define MMC_STAT_FLASH_ERR      (1 << 9)        /* Flash programming error
                                                   occurred */
#define MMC_STAT_CLK_EN         (1 << 8)        /* MMC/SDIO clock is on */
#define MMC_STAT_RES_CRC_ERR    (1 << 5)        /* Response CRC error */
#define MMC_STAT_DAT_ERR_TOKEN  (1 << 4)        /* SPI data error token recv*/
#define MMC_STAT_CRC_RD_ERR     (1 << 3)        /* CRC error on receive */
#define MMC_STAT_CRC_WR_ERR     (1 << 2)        /* Write data rejected due to
                                                   CRC error */
#define MMC_STAT_TIME_OUT_RES   (1 << 1)        /* Card response timed out */
#define MMC_STAT_TIME_OUT_READ  (1 << 0)        /* Card read data timed out*/
#define MMC_STAT_ALL            (0x1ffff)
#define MMC_CLKRT       __REG(0x41100008)       /* MMC clock rate */
#define MMC_CLKRT_FREQ          (7 << 0)        /* Clock Frequency: */
#define MMC_CLKRT_FREQ_19_5MHZ  (0 << 0)        /*      19.5 MHz */
#define MMC_CLKRT_FREQ_9_75MHZ  (1 << 0)        /*      9.75 MHz */
#define MMC_CLKRT_FREQ_4_88MHZ  (2 << 0)        /*      4.88 MHz */
#define MMC_CLKRT_FREQ_2_44MHZ  (3 << 0)        /*      2.44 MHz */
#define MMC_CLKRT_FREQ_1_22MHZ  (4 << 0)        /*      1.22 MHz */
#define MMC_CLKRT_FREQ_609KHZ   (5 << 0)        /*      609 KHz */
#define MMC_CLKRT_FREQ_304KHZ   (6 << 0)        /*      304 KHz */

#define MMC_SPI         __REG(0x4110000c)       /* SPI mode control bits */
#define MMC_SPI_CS_ADDRESS      (1 << 3)        /* Enable CS1 or CS0 */
#define MMC_SPI_CS_EN           (1 << 2)        /* Enable SPI Chip Select */
#define MMC_SPI_CRC_EN          (1 << 1)        /* Enable CRC generation and
                                                   verification */
#define MMC_SPI_MODE            (1 << 0)        /* Enable SPI mode */

#define MMC_CMDAT       __REG(0x41100010)       /* Command/response/data sequence control */
#define MMC_CMDAT_SDIO_RESUME   (1 << 13)       /* SDIO CMD52, resume a
                                                   suspended data transfer */
#define MMC_CMDAT_SDIO_SUSPEND  (1 << 12)       /* SDIO CMD52, suspend current
                                                   data transfer */
#define MMC_CMDAT_SDIO_INT_EN   (1 << 11)       /* Enable check for SDIO
                                                   interrupt from card */
#define MMC_CMDAT_STOP_TRAN     (1 << 10)       /* Stop data transmission */
#define MMC_CMDAT_SD_4DAT       (1 << 8)        /* Enable 4-bit data transfer*/


#define MMC_CMDAT_DMA_EN        (1 << 7)        /* Enable DMA access to FIFO */
#define MMC_CMDAT_INIT          (1 << 6)        /* Precede command sequence
                                                   with 80 clocks, for
                                                   initialisation */
#define MMC_CMDAT_BUSY          (1 << 5)        /* Specifies whether a busy
                                                   signal possible after the
                                                   current command */
#define MMC_CMDAT_STRM_BLK      (1 << 4)        /* Data transfer is in
                                                   stream mode */
#define MMC_CMDAT_WR            (1 << 3)        /* Data transfer is a write
                                                   operation */
#define MMC_CMDAT_RD            (0 << 3)        /* Data transfer is a read
                                                   operation */
#define MMC_CMDAT_DATA_EN       (1 << 2)        /* Current command includes
                                                   a data transfer */
#define MMC_CMDAT_RES_TYPE      (3 << 0)        /* Command reponse format */
#define MMC_CMDAT_RES_NORESP    (0 << 0)        /*      No response */
#define MMC_CMDAT_RES_RESP      (1 << 0)        /*      Response with CRC */
#define MMC_CMDAT_RES_R2        (2 << 0)        /*      CID/CSD response */
#define MMC_CMDAT_RES_R3        (3 << 0)        /*      R3 response */
#define MMC_RESTO       __REG(0x41100014)  /* Expected response time out */
#define MMC_RESTO_MASK          (0x0000007f)
#define MMC_RDTO        __REG(0x41100018)  /* Expected data read time out */
#define MMC_RDTO_MASK           (0x0000ffff)
#define MMC_BLKLEN      __REG(0x4110001c)  /* Block length of data transaction */
#define MMC_BLKLEN_MASK         (0x00000fff)
#define MMC_NOB         __REG(0x41100020)  /* Number of blocks, for block mode */
#define MMC_NOB_MASK            (0x0000ffff)
#define MMC_PRTBUF      __REG(0x41100024)  /* Partial MMC_TXFIFO FIFO written */
#define MMC_PRTBUF_PRT_FULL     (1 << 0)        /* Buffer is partially full */
#define MMC_I_MASK      __REG(0x41100028)  /* Interrupt Mask */
#define MMC_I_REG       __REG(0x4110002c)  /* Interrupt Register (read only) */
#define MMC_I_SDIO_SUSPEND_ACK  (1 << 12)       /* SDIO data transfer has been
                                                   suspended by SDIO card */
#define MMC_I_SDIO_INT          (1 << 11)       /* An SDIO interrupt occured*/
#define MMC_I_RD_STALLED        (1 << 10)       /* Card has stalled read */
#define MMC_I_RES_ERR           (1 << 9)        /* Error occured on the resp */
#define MMC_I_DAT_ERR           (1 << 8)        /* Data error occurred during
                                                   data transmission */
#define MMC_I_TINT              (1 << 7)        /* Transmit Interrupt */
#define MMC_I_TXFIFO_WR_REQ     (1 << 6)        /* Tx FIFO Write Request */
#define MMC_I_TXFIFO_RD_REQ     (1 << 5)        /* Rx FIFO Read Request */
#define MMC_I_CLK_IS_OFF        (1 << 4)        /* Clock is Off */
#define MMC_I_STOP_CMD          (1 << 3)        /* MMC is ready for the stop
                                                   transmission command */
#define MMC_I_END_CMD_RES       (1 << 2)        /* End Command Response */
#define MMC_I_PRG_DONE          (1 << 1)        /* Programming Done */
#define MMC_I_DATA_TRAN_DONE    (1 << 0)        /* Data Transfer Done */
#define MMC_I_ALL               (0x00001fff)

#define MMC_CMD         __REG(0x41100030)  /* Index of current command */
#define MMC_CMD_MASK            (0x0000003f)

#define MMC_ARGH        __REG(0x41100034)  /* MSW part of the current command argument */
#define MMC_ARGH_MASK           (0x0000ffff)

#define MMC_ARGL        __REG(0x41100038)  /* LSW part of the current command argument */
#define MMC_ARGL_MASK           (0x0000ffff)
#define MMC_RES         __REG(0x4110003c)  /* Response FIFO (read only) */
#define MMC_RXFIFO      __REG(0x41100040)  /* Receive FIFO (read only) */
#define MMC_TXFIFO      __REG(0x41100044)  /* Transmit FIFO (write only) */
#define MMC_RDWAIT      __REG(0x41100048)  /* RD_WAIT operation to SDIO card */
#define MMC_RDWAIT_START        (1 << 1)        /* Restart the read data tran*/
#define MMC_RDWAIT_EN           (1 << 0)        /* RD_WAIT enable */
#define MMC_BLKS_REM    __REG(0x4110004c)  /* Number of data blocks which are
                                              not transferred */
#define MMC_BLKS_REM_MASK       (0x0000ffff)
#define PGSR(x)        __REG(0x40F00020 + ((unsigned long)(x)/32 * 4))


修改bvd_mmc.c
在void bvd_mmc_slot_up(void) 函数里修改相关的管脚属性
set_GPIO_mode(GPIO_MMC_CLK | GPIO_ALT_FN_1_OUT);
set_GPIO_mode(
GPIO_MMC_MMCCS0 | GPIO_ALT_FN_1_OUT);

make zImage

下载到目标板运行,经过测试可支持2G的SD卡。