上期通过三星Internal ROM Application Note提供了启动设备的复制函数,实现了u-boot从sd卡启动。本期完成MMC驱动的移植。
1. 代码修改
1.1 修改include/configs/tiny6410.h,增加
/* MMC */
#define CONFIG_GENERIC_MMC 1
#define CONFIG_MMC 1
#define CONFIG_S3C64X0_MMC 1
#define CONFIG_CMD_MMC /* MMC support */
1.2 修改board/samsung/tiny6410/tiny6410.c,增加
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
return s3c64x0_mmc_init(0);
}
#endif
1.3 修改drivers/mmc/Makefile,增加
COBJS-$(CONFIG_S3C64X0_MMC) += s3c64x0_mmc.o
1.4 修改arch/arm/include/asm/arch-s3c64xx/s3c64x0.h,增加
/* MMC */
struct s3c64x0_mmc {
unsigned int sysad;
unsigned short blksize;
unsigned short blkcnt;
unsigned int argument;
unsigned short trnmod;
unsigned short cmdreg;
unsigned int rspreg0;
unsigned int rspreg1;
unsigned int rspreg2;
unsigned int rspreg3;
unsigned int bdata;
unsigned int prnsts;
unsigned char hostctl;
unsigned char pwrcon;
unsigned char blkgap;
unsigned char wakcon;
unsigned short clkcon;
unsigned char timeoutcon;
unsigned char swrst;
unsigned int norintsts; /* errintsts */
unsigned int norintstsen; /* errintstsen */
unsigned int norintsigen; /* errintsigen */
unsigned short acmd12errsts;
unsigned char res1[2];
unsigned int capareg;
unsigned char res2[4];
unsigned int maxcurr;
unsigned char res3[0x34];
unsigned int control2;
unsigned int control3;
unsigned int control4;
unsigned char res4[0x6e];
unsigned short hcver;
unsigned char res5[0xFFF02];
};
1.5 修改arch/arm/include/asm/arch-s3c64xx/s3c6400.h,增加
#define ELFIN_MMC_BASE 0x7C200000
struct mmc_host {
struct s3c64x0_mmc *reg;
unsigned int version; /* SDHCI spec. version */
unsigned int clock; /* Current clock (MHz) */
};
int s3c64x0_mmc_init(int dev_index);
static inline void *samsung_get_base_mmc(void)
{
return (void *)(ELFIN_MMC_BASE);
}
1.6 在drivers/mmc/下新建s3c64x0_mmc.c,代码如下:
/*
* (C) Copyright 2009 SAMSUNG Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Jaehoon Chung <jh80.chung@samsung.com>
*
* modified by Tekkaman Ninja for s3c64x0 <tekkamanninja@gmail.com>
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//#define DEBUG
#include <common.h>
//#undef DEBUG
#include <mmc.h>
#include <asm/io.h>
//#include <asm/arch/mmc.h>
#include <asm/arch/s3c64x0.h>
#include <asm/arch/s3c6400.h>
/* support 3 mmc hosts */
struct mmc mmc_dev[3];
struct mmc_host mmc_host[3];
static inline struct s3c64x0_mmc *s3c64x0_get_base_mmc(int dev_index)
{
unsigned long offset = dev_index * sizeof(struct s3c64x0_mmc);
return (struct s3c64x0_mmc *)(samsung_get_base_mmc() + offset);
}
static int mmc_card_detect(struct mmc_host *mmc_host)
{
return (mmc_host->reg->prnsts & (0x5 << 16));
}
static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data)
{
unsigned char ctrl;
debug("data->dest: %08x\n", (u32)data->dest);
writel((u32)data->dest, &host->reg->sysad);
/*
* DMASEL[4:3]
* 00 = Selects SDMA
* 01 = Reserved
* 10 = Selects 32-bit Address ADMA2
* 11 = Selects 64-bit Address ADMA2
*/
ctrl = readb(&host->reg->hostctl);
ctrl &= ~(3 << 3);
writeb(ctrl, &host->reg->hostctl);
/* We do not handle DMA boundaries, so set it to max (512 KiB) */
writew((7 << 12