summaryrefslogtreecommitdiff
path: root/board/st/u8500
diff options
context:
space:
mode:
Diffstat (limited to 'board/st/u8500')
-rw-r--r--board/st/u8500/Makefile2
-rw-r--r--board/st/u8500/common.h3
-rw-r--r--board/st/u8500/emmc.c391
-rwxr-xr-xboard/st/u8500/emmc.h36
-rw-r--r--board/st/u8500/init_mmc.c214
-rwxr-xr-xboard/st/u8500/init_mmc.h43
-rw-r--r--board/st/u8500/mmc.c2594
-rw-r--r--board/st/u8500/mmc.h263
-rw-r--r--board/st/u8500/mmc_host.c636
-rw-r--r--board/st/u8500/mmc_host.h296
-rwxr-xr-xboard/st/u8500/mmc_p.h315
-rw-r--r--board/st/u8500/mmc_utils.c974
-rwxr-xr-xboard/st/u8500/mmc_utils.h107
-rw-r--r--board/st/u8500/u8500.c8
14 files changed, 1050 insertions, 4832 deletions
diff --git a/board/st/u8500/Makefile b/board/st/u8500/Makefile
index ccaae6aa5..c151f72b5 100644
--- a/board/st/u8500/Makefile
+++ b/board/st/u8500/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
CFLAGS += -D__RELEASE -D__STN_8500
LIB = $(obj)lib$(BOARD).a
-COBJS := u8500.o flash.o gpio.o u8500_i2c.o mmc.o mmc_utils.o init_mmc.o emmc.o clock.o prcmu.o mcde_display.o mcde_hw.o ab8500vibra.o
+COBJS := u8500.o flash.o gpio.o u8500_i2c.o mmc_host.o mmc_utils.o clock.o prcmu.o mcde_display.o mcde_hw.o ab8500vibra.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/st/u8500/common.h b/board/st/u8500/common.h
index 07c97bea5..a11b605f5 100644
--- a/board/st/u8500/common.h
+++ b/board/st/u8500/common.h
@@ -128,7 +128,6 @@ typedef u32 t_logical_address;
/*function prototypes*/
void gpio_init(void);
-int emmc_init (u8);
-extern int u8500_is_earlydrop(void);
+int u8500_is_earlydrop(void);
#endif /* _COMMON_H_ */
diff --git a/board/st/u8500/emmc.c b/board/st/u8500/emmc.c
deleted file mode 100644
index 7336b0334..000000000
--- a/board/st/u8500/emmc.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
-* Copyright (C) ST-Ericsson SA 2009
-*
-* See file CREDITS for list of people who contributed to this
-* project.
-*
-* 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
-*/
-/* --- includes ----------------------------------------------------------- */
-#include "common.h" /* XXX: Arrgghh! "common.h" includes <common.h> */
-#include <command.h>
-#include "mmc.h"
-#include "emmc.h"
-#include "gpio.h"
-#include <boottime.h>
-
-#define PIB_EMMC_ADDR 0x00
-/* ========================================================================
-Name: init_emmc
-Description: init embedded multimedia card interface
-
-======================================================================== */
-int emmc_init(u8 card_num)
-{
- t_mmc_error mmc_error;
- t_mmc_error response;
- gpio_error gpioerror;
- t_logical_address mmcbase;
- int error;
-
- mmcbase = u8500_is_earlydrop() ? CFG_EMMC_BASE_ED : CFG_EMMC_BASE_V1;
-
-/* Initialize the base address of eMMC */
- mmc_error = mmc_init(card_num, mmcbase);
-
- if (MMC_OK != mmc_error)
- {
- printf("emmc_init() %d \n", mmc_error);
- goto end;
- }
-
- /*
- * FIXME The following code is not required on v1. Check if it is really
- * needed on ED or can be dropped.
- */
- if (u8500_is_earlydrop()) {
-#ifndef CONFIG_U8500_V1
- /* Initialize the gpio alternate function for eMMC */
- struct gpio_register *p_gpio_register = (void *) IO_ADDRESS(CFG_GPIO_6_BASE);
- p_gpio_register -> gpio_dats |= 0x0000FFE0;
- p_gpio_register -> gpio_pdis &= ~0x0000FFE0;
-
- //enable the alternate function of EMMC
- gpioerror = gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
- if(gpioerror != GPIO_OK)
- {
- printf("emmc_init() gpio_altfuncenable %d failed\n", gpioerror);
- goto end;
- }
-
-#else
- //enable the alternate function of PoP EMMC
- // gpioerror = gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
- gpioerror = gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
- if (gpioerror != GPIO_OK) {
- printf("emmc_init() gpio_altfuncenable %d failed \n",
- gpioerror);
- goto end;
- }
-#endif
- }
-
- //Power-on the controller
- response = mmc_poweron(card_num);
- if (response != MMC_OK)
- {
- printf("Error in eMMC power on, response is %d\n",response);
- goto end;
- }
- // Initialise the cards,get CID and CSD on the bus
- response = mmc_initializeCards(card_num);
-
- if (response != MMC_OK)
- {
- printf(" Error in eMMC initialization\n");
- goto end;
- }
-
- error = emmc_write_pib();
- if(error)
- printf("PIB info writing into eMMC failed\n");
- printf("eMMC done\n");
-
- return 0;
-
-end:
- mmc_poweroff(card_num);
- return 1;
-}
-
-struct partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- u32 start_sect; /* starting sector counting from 0 */
- u32 nr_sects; /* nr of sectors in partition */
-} __attribute__((packed));
-
-#define PART(type, start, num) \
- { \
- .boot_ind = 0x00, \
- .head = 0x03, \
- .sector = 0xD0, \
- .cyl = 0xff, \
- .sys_ind = type, \
- .end_head = 0x03, \
- .end_sector = 0xd0, \
- .end_cyl = 0xff, \
- .start_sect = start, \
- .nr_sects = num, \
- }
-
-static struct partition partitions_ed[] = {
- [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
- [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
- [2] = PART(0x83, 0x00124000, 0x0022c000),
- [3] = PART(0x0c, 0x00350000, 0x00b9a000),
-};
-
-static struct partition partitions_v1[] = {
- [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
- [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
- [2] = PART(0x83, 0x00124000, 0x00000800), /* Modem parameters */
- [3] = {0},
-};
-
-#undef PART
-
-int emmc_write_pib(void)
-{
- int i;
- t_mmc_error mmc_error;
- u32 block_offset = PIB_EMMC_ADDR;
- u8 card_num = 4;
- u8 mbr[512];
-
- memset(mbr, 0, 0x1be);
-
- if (u8500_is_earlydrop())
- memcpy(mbr + 0x1be, partitions_ed, sizeof(partitions_ed));
- else
- memcpy(mbr + 0x1be, partitions_v1, sizeof(partitions_v1));
-
- /* magic */
- mbr[0x1fe] = 0x55;
- mbr[0x1ff] = 0xAA;
-
-/* HACK required for HREF board as erase block size = 512KB */
-/*
- mmc_error = mmc_erase(card_num, 0x0, 0x1FF);
- if (mmc_error != MMC_OK) {
- printf(" eMMC erase failed in PIB \n");
- return 1;
- }
-*/
-
- mmc_error =
- mmc_writeblocks(card_num, block_offset, (u32 *) mbr,
- 512, 1);
- if (mmc_error != MMC_OK) {
- printf(" eMMC PIB write failed \n");
- return 1;
- }
- return 0;
-}
-
-int emmc_erase(u32 start, u32 end)
-{
- t_mmc_error mmc_error;
- u8 card_num = 4;
- printf("emmc erase start \n");
- mmc_error = mmc_erase(card_num, start, end);
- if (mmc_error != MMC_OK) {
- printf(" eMMC erase failed \n");
- return 1;
- }
- printf("emmc erase done \n");
- return 0;
-}
-
-int emmc_read(u32 block_offset, u32 read_buffer, u32 filesize)
-{
- t_mmc_error mmc_error;
- u32 remaining;
- u8 card_num = 4;
- u8 *mem_address = (u8 *) read_buffer;
- u32 n=filesize,blocks;
-
- remaining = filesize;
-
- printf(" eMMC read start filesize=0x%x \n", filesize);
-
- blocks = (n%512==0)?(n/512):(n/512)+1;
-
- while(blocks>=8)
- {
- mmc_error = mmc_readblocks(card_num, block_offset, (u32 *) mem_address, 512, 8);
- if (mmc_error != MMC_OK)
- {
- printf(" eMMC read blocks failed \n");
- return 1;
- }
-
- block_offset += 4096;
- mem_address += 4096;
- blocks -=8;
- remaining -= 4096;
- }
- if(blocks)
- {
- mmc_error = mmc_readblocks(card_num, block_offset, (u32 *) mem_address, 512, blocks);
- if (mmc_error != MMC_OK)
- {
- printf(" eMMC read blocks failed \n");
- return 1;
- }
- }
-
- printf(" eMMC read done \n");
- return 0;
-}
-
-int emmc_write(u32 block_offset, u32 write_buffer, u32 filesize)
-{
- t_mmc_error mmc_error;
- u32 remaining;
- u8 card_num = 4;
- u8 *mem_address = (u8 *) write_buffer;
- u32 n=filesize,blocks;
-
- remaining = filesize;
-
- printf(" eMMC write start filesize=0x%x \n", filesize);
-
- blocks = (n%512==0)?(n/512):(n/512)+1;
- while(blocks>=8)
- {
- mmc_error = mmc_writeblocks(card_num, block_offset, (u32 *) mem_address,512, 8);
- if (mmc_error != MMC_OK)
- {
- printf(" eMMC write blocks failed \n");
- return 1;
- }
-
- block_offset += 4096;
- mem_address += 4096;
- blocks -=8;
- remaining -= 4096;
- }
- if(blocks)
- {
-
- mmc_error = mmc_writeblocks(card_num, block_offset, (u32 *) mem_address,512, blocks);
- if (mmc_error != MMC_OK)
- {
- printf(" eMMC write blocks failed \n");
- return 1;
- }
-
- }
-
- printf(" eMMC write done \n");
- return 0;
-}
-
-/*
- * command line commands
- */
-#ifdef CONFIG_CMD_EMMC
-int do_emmc_erase(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- u32 start_address;
- u32 end_address;
- int load_result = 1;
- u32 error_name = 0;
-
- start_address = simple_strtoul(argv[1],0,16);
- end_address = simple_strtoul(argv[2],0,16);
-
- printf("emmc_erase :: start address = %x end_address=0x%x\n",start_address,end_address);
-
- load_result = emmc_erase(start_address,end_address);
- if (load_result != 0)
- {
- error_name = (unsigned long) (-load_result);
- printf("emmc_erase error : failed \n");
- }
- return(0);
-}
-
-U_BOOT_CMD(
- emmc_erase, 3, 0, do_emmc_erase,
- "- erase the eMMC flash \n",
- "start_address- start address of the eMMC block\n"
- "end_address- end address of the eMMC block\n"
-);
-
-int do_emmc_read(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- u32 ram_address;
- u32 block_offset;
- u32 filesize;
- int load_result = 1;
- u32 error_name = 0;
-
- ram_address = simple_strtoul (argv[1],0,16);
- block_offset = simple_strtoul (argv[2],0,16);
- filesize = simple_strtoul (argv[3],0,16);
-
- boottime_tag("load_image");
- printf("emmc_read :: ram address = 0x%x block address=0x%x \n",ram_address,block_offset);
-
- load_result = emmc_read(block_offset,ram_address,filesize);
- if (load_result != 0)
- {
- boottime_remove_last();
- error_name = (unsigned long) (-load_result);
- printf("emmc_read error : in reading data from eMMC block \n");
- }
- return(0);
-}
-
-U_BOOT_CMD(
- emmc_read, 4, 0, do_emmc_read,
- "- read file from emmc flash \n",
- "ram_address - read from eMMC and copy into ram address\n"
- "block_offset - address to read the file from the eMMC block \n"
- "filesize - size of the file \n"
-);
-
-int do_emmc_write(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- u32 ram_address;
- u32 block_offset;
- u32 filesize;
- int load_result = 1;
- u32 error_name = 0;
-
- ram_address = simple_strtoul (argv[1],0,16);
- block_offset = simple_strtoul (argv[2],0,16);
- filesize = simple_strtoul (argv[3],0,16);
-
- printf("emmc_write :: ram address = %x block address=0x%x \n",ram_address,block_offset);
-
- load_result = emmc_write(block_offset,ram_address,filesize);
- if (load_result != 0)
- {
- error_name = (unsigned long) (-load_result);
- printf("emmc_read error : in writing data into eMMC block \n");
- }
- return(0);
-}
-
-U_BOOT_CMD(
- emmc_write, 4, 0, do_emmc_write,
- "- write file from emmc flash \n",
- "ram_address - write to eMMC by copying from ram address\n"
- "block_offset - address to write the file into the eMMC block \n"
- "filesize - size of the file \n"
-);
-
-#endif /* CONFIG_CMD_EMMC */
-/* ------------------------------- End of file ---------------------------- */
diff --git a/board/st/u8500/emmc.h b/board/st/u8500/emmc.h
deleted file mode 100755
index 62256ae9e..000000000
--- a/board/st/u8500/emmc.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-
-#ifndef _STM_EMMC_H
-#define _STM_EMMC_H
-
-
-#include <common.h>
-
-extern int emmc_init (u8);
-int emmc_erase(u32, u32);
-int emmc_read (u32,u32,u32);
-int emmc_write(u32,u32,u32);
-int emmc_write_pib(void);
-
-
-#endif /* !defined(_STM_EMMC_H) */
diff --git a/board/st/u8500/init_mmc.c b/board/st/u8500/init_mmc.c
deleted file mode 100644
index fb6470a23..000000000
--- a/board/st/u8500/init_mmc.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-/* --- includes ----------------------------------------------------------- */
-#include "common.h"
-#include "mmc.h"
-#include "init_mmc.h"
-#include "gpio.h"
-#include "mmc_utils.h"
-
-#ifdef CONFIG_CMD_FAT
-#include <part.h>
-#include <fat.h>
-#endif
-
-#define MMC_CARD_NUM 1
-#define EMMC_CARD_NUM 4
-enum {
- DEV_EMMC = 0,
- DEV_MMC
-};
-
-static block_dev_desc_t mmc_dev;
-static block_dev_desc_t emmc_dev;
-static u32 CSD[4];
-
-block_dev_desc_t * mmc_get_dev(int dev)
-{
- if (dev == DEV_EMMC)
- return (block_dev_desc_t *)(&emmc_dev);
- else if (dev == DEV_MMC)
- return (block_dev_desc_t *)(&mmc_dev);
-
- printf("mmc_get_dev: unknown dev %d\n", dev);
- return 0;
-}
-
-static unsigned long emmc_block_read(int dev, unsigned long blknr,
- lbaint_t blkcnt, void *dest)
-{
- unsigned long rc;
-
- rc = mmc_readblocks(EMMC_CARD_NUM, (u32) (512 * blknr), (u32 *)dest,
- 512, blkcnt);
- if (rc != 0) {
- printf("mmc_block_read: readblocks failed %ld\n", rc);
- rc = 0;
- } else {
- rc = blkcnt;
- }
- return rc;
-}
-
-unsigned long mmc_block_read(int dev, unsigned long blknr,
- lbaint_t blkcnt, void *dest)
-{
- unsigned long i;
- unsigned long src= blknr;
- unsigned long rc = 0;
-
- for(i = 0; i < blkcnt; i++)
- {
- /* card#, read offset, buffer, blksize, transfer mode */
- mmc_readblock(MMC_CARD_NUM, (u32) (512 * src),
- (u32 *)dest, 512, MMCPOLLING);
- rc++;
- src++;
- dest += 512;
- }
- return rc;
-}
-
-int mmc_hw_init(void)
-{
- t_mmc_error response;
-
- /* save the GPIO0 AFSELA register*/
- gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
- /* Power-on the controller*/
- response = mmc_enable ();
-
- if (response != MMC_OK)
- {
- response = mmc_enable ();
- if (response != MMC_OK)
- {
- printf ("Error in card power on\n");
- goto end;
- }
- }
- /* Initialise the cards on the bus, if any*/
- response = mmc_initCard ();
- if (response != MMC_OK)
- {
- printf ("Error in card initialization\n");
- goto end;
- }
- response = mmc_readcsd (CSD);
- if (response != MMC_OK)
- {
- printf ("Error while fetching card info\n");
- goto end;
- }
-
- return 0;
- end:
- return 1;
-}
-
-/*
- * mmc_legacy_init - called from commandline mmc init <dev>
- *
- * Initialise hardware and setup block device structure for fat and ext2
- * commands.
- */
-int mmc_legacy_init(int dev)
-{
-
- if (dev == DEV_EMMC) {
- debug("EMMC init\n");
- /* XXX: emmc_init() does write the MBR (called pib)! */
- emmc_init(EMMC_CARD_NUM);
- emmc_dev.if_type = IF_TYPE_MMC;
- emmc_dev.part_type = PART_TYPE_DOS;
- emmc_dev.dev = dev;
- emmc_dev.lun = 0;
- emmc_dev.type = 0;
- emmc_dev.blksz = 512;
- emmc_dev.lba = 0x80000; /* XXX: use real size, here 256 MB */
- sprintf((char*)emmc_dev.vendor, "Unknown vendor");
- sprintf((char*)emmc_dev.product, "Unknown product");
- sprintf((char*)emmc_dev.revision, "N/A");
- emmc_dev.removable = 0;
- emmc_dev.block_read = emmc_block_read;
- return 0;
- } else if (dev == DEV_MMC) {
- debug("MMC init\n");
- return init_mmc();
- }
-
- printf("mmc_legacy_init: unsupported device# %d\n", dev);
- return -1;
-}
-
-/* ========================================================================
- Name: init_mmc
- Description: init multimedia card interface
-
- ======================================================================== */
-static int init_mmc(void)
-{
- t_mmc_error mmc_error;
- struct gpio_register * gpio_base_address;
-
- /* Initialize the base address of MMC-SD */
- mmc_error = mmc_init (0,CFG_MMC_BASE);
-
- if (MMC_OK != mmc_error)
- {
- printf("mmc_init():: %d \n", mmc_error);
- return 1 ;
- }
-
- if (u8500_is_earlydrop()) {
- gpio_base_address = (void *) IO_ADDRESS(CFG_GPIO_0_BASE);
- gpio_base_address -> gpio_dats |= 0xFFC0000;
- gpio_base_address -> gpio_pdis &= ~0xFFC0000;
- }
-
- if (mmc_hw_init() != 0) {
- printf("mmc_init: hw init failed\n");
- return -1;
- }
- mmc_dev.if_type = IF_TYPE_MMC;
- mmc_dev.part_type = PART_TYPE_DOS;
- mmc_dev.dev = 0;
- mmc_dev.lun = 0;
- mmc_dev.type = 0;
- mmc_dev.blksz = 512;
- mmc_dev.lba = 0x20000; /* XXX: use real size, here 64 MB */
- sprintf((char*)mmc_dev.vendor, "Unknown vendor");
- sprintf((char*)mmc_dev.product, "Unknown product");
- sprintf((char*)mmc_dev.revision, "N/A");
- mmc_dev.removable = 0;
- mmc_dev.block_read = mmc_block_read;
-#ifdef CONFIG_CMD_FAT
- if (fat_register_device(&mmc_dev, 1) != 0) {
- printf("mmc_init: could not register as FAT device\n");
- }
-#endif /* CONFIG_CMD_FAT */
-
- return 0;
-}
-
-
-/* ------------------------------- End of file ---------------------------- */
diff --git a/board/st/u8500/init_mmc.h b/board/st/u8500/init_mmc.h
deleted file mode 100755
index b66f866f8..000000000
--- a/board/st/u8500/init_mmc.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-
-#ifndef __INIT_MMC_H
-#define __INIT_MMC_H
-#define PUBLIC /* Extern by default */
-
-#include <common.h>
-
-typedef void (*t_callback_fct) (u32);
-typedef struct
-{
- t_callback_fct fct;
- u32 param;
-} t_callback;
-
-static int init_mmc(void);
-int init_mmc_fat(void);
-t_mmc_error mmc_fat_read_file (char *, u32, u32);
-int mmc_hw_init (void);
-unsigned long mmc_block_read(int dev,unsigned long blknr,lbaint_t blkcnt,void *dest);
-
-
-#endif /* !defined(__INIT_MMC_H) */
diff --git a/board/st/u8500/mmc.c b/board/st/u8500/mmc.c
deleted file mode 100644
index 97508af8d..000000000
--- a/board/st/u8500/mmc.c
+++ /dev/null
@@ -1,2594 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-#include <asm/types.h>
-#include <asm/io.h>
-#include <asm/errno.h>
-
-#include <configs/u8500.h>
-#include "common.h"
-#include "mmc.h"
-#include "mmc_p.h"
-
-#define MAX_NUM_CARDS 5
-t_mmc_register *t_mmc0; /* Removed so it can be used in mmc_utils.c, by Chris S. */
-t_mmc_register *t_mmc4;
-t_mmc_register *t_mmc[MAX_NUM_CARDS];
-u32 t_mmc_rel_addr = 0x00010000;
-u32 emmc_rel_addr = 0x00100000;
-u8 no_of_cards = 0;
-u8 mmc_card = 0, sd_card = 0;
-u32 clockfreq;
-t_mmc_card_info card_array[30];
-t_mmc_device_mode device_mode = POLLING_MODE;
-u32 *source_buffer;
-u32 *dest_buffer;
-u16 total_no_of_bytes = 0;
-u8 selected_card = 0;
-t_mmc_error transfer_error = MMC_CMD_CRC_FAIL;
-u32 pwddata[8];
-t_mmc_event mmc_event; // For event management
-u32 write_freq = 0;
-
-/* Private Functions*/
-t_mmc_error mmc_cmderror(u8);
-t_mmc_error mmc_cmdresp145error(u8, u8);
-t_mmc_error mmc_cmdresp2error(u8);
-t_mmc_error mmc_cmdresp3error(u8);
-t_mmc_error mmc_cmdresp6error(u8, u16 *, u8);
-t_mmc_error mmc_cmdresp7error(u8);
-t_mmc_error mmc_findblocklen(u16 nobytes, u8 * power);
-t_mmc_error mmc_sendstatus(u8, u32 *);
-t_mmc_error mmc_iscardprogramming(u8, u8 *);
-
-/****************************************************************************/
-/* NAME : mmc_init() */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine initializes the MMC registers, checks */
-/* Peripheral and PCell Id and clears all interrupts. */
-/* PARAMETERS : */
-/* IN : t_logical_address MMCBaseAddress:MMC registers base address */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error : MMC error code */
-/****************************************************************************/
-
-t_mmc_error mmc_init(u8 card_num, t_logical_address MMCBaseAddress)
-{
- t_mmc_error error;
- if (card_num == 0)
- t_mmc0 = (t_mmc_register *) MMCBaseAddress;
- else if (card_num == 4)
- t_mmc[card_num] = (t_mmc_register *) MMCBaseAddress;
- error = MMC_OK;
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_setpowerstate() */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets the power status of the controller. */
-/* */
-/* PARAMETERS : */
-/* IN : t_mmc_Power_state Power state to set */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error : MMC error code */
-/****************************************************************************/
-t_mmc_error mmc_setpowerstate(t_mmc_power_state MMCPowerState)
-{
- t_mmc_error error;
-
- MMC_SET_CTRL(t_mmc0->mmc_Power, MMCPowerState);
- error = MMC_OK;
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_getpowerstate() */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine returns the power status of the controller. */
-/* */
-/* PARAMETERS : */
-/* IN : t_mmc_Power_state Power state to set */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error : MMC error code */
-/****************************************************************************/
-
-t_mmc_power_state mmc_getpowerstate()
-{
- t_mmc_power_state state;
- state = MMC_READ_BITS(t_mmc0->mmc_Power, MMC_Power_MASK_CTRL, sbMMC_Power_CTRL);
- return (state);
-}
-
-/*****************************************************************************/
-/* NAME : mmc_setoperatingvoltage */
-/*-------------------------------------------------------------------------- */
-/* DESCRIPTION: This routine sets the operating voltage range of . */
-/* the controller */
-/* PARAMETERS : */
-/* IN : u8 The encoded value of the output voltage range to set.*/
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error : MMC error code */
-/*****************************************************************************/
-
-t_mmc_error mmc_setoperatingvoltage(u8 value)
-{
- t_mmc_error error;
- if (value < 16)
- {
- MMC_SET_VOLT(t_mmc0->mmc_Power, value);
- error = MMC_OK;
- }
- else
- error = MMC_INVALID_PARAMETER;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_getoperatingvoltage */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine returns the encoded value of the current */
-/* operating voltage range */
-/* PARAMETERS : */
-/* IN : */
-/* OUT : */
-/* */
-/* RETURN : u8 The encoded value of the output voltage range to set*/
-/****************************************************************************/
-
-u8 mmc_getoperatingvoltage()
-{
- u8 voltage;
- voltage =
- MMC_READ_BITS(t_mmc0->mmc_Power, MMC_Power_MASK_VOLT,sbMMC_Power_VOLT);
- return (voltage);
-}
-
-/****************************************************************************/
-/* NAME : mmc_configbus */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine configures the bus in open drain or . */
-/* push-pull mode */
-/* PARAMETERS : */
-/* IN : t_mmc_bus_configuration Bus configuration to set */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_configbus(t_mmc_bus_configuration busconfig)
-{
- t_mmc_error error;
- MMC_SET_OPEND(t_mmc0->mmc_Power, busconfig.mode);
- MMC_SET_ROD(t_mmc0->mmc_Power, busconfig.rodctrl);
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_setclock */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets the clock state as enabled or disabled. */
-/* */
-/* PARAMETERS : */
-/* IN : t_mmc_state clock state to set. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_setclock(t_mmc_state busstate)
-{
- t_mmc_error error;
- MMC_SET_CENABLE(t_mmc0->mmc_Clock, busstate);
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_configclockcontrol */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets configurations for clock and bus mode. */
-/* */
-/* PARAMETERS : */
-/* IN : t_mmc_Clock_control clock control state to set. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_configclockcontrol(t_mmc_clock_control clockcontrol)
-{
- t_mmc_error error;
-
- MMC_SET_PWRSAVE(t_mmc0->mmc_Clock, clockcontrol.pwrsave);
- MMC_SET_BYPASS(t_mmc0->mmc_Clock, clockcontrol.bypass);
- MMC_SET_WIDEBUS(t_mmc0->mmc_Clock, clockcontrol.widebus);
- error = MMC_OK;
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_setclockfrequency */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets clock frequency for MMCI controller. */
-/* */
-/* PARAMETERS : */
-/* IN : u8 Clock divider value for desired frequency. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/* COMMENT: Clock frequency is calculated by this formula: */
-/* MCICLK = MCLK/(2 * [Clock_div +1]) */
-
-/****************************************************************************/
-
-t_mmc_error mmc_setclockfrequency(u8 clockdiv)
-{
- t_mmc_error error;
-
- MMC_SET_CLKDIV(t_mmc0->mmc_Clock, clockdiv);
- error = MMC_OK;
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_sendcommand */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sends command and enable Command path */
-/* state machine. */
-/* PARAMETERS : */
-/* IN : t_mmc_Command_index: Command to send. */
-/* u32: argument to send. */
-/* t_mmc_Command_control: Command control parameters to set. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_sendcommand(t_mmc_command_index commandindex, u32 argument,
- t_mmc_command_control commcontrol)
-{
- t_mmc_error error;
- u32 reg;
-
- if (commandindex != MMC_NO_CMD)
- {
- reg = commandindex;
- t_mmc0->mmc_Argument = argument;
- reg |= (commcontrol.IsRespExpected << 6);
- reg |= (commcontrol.IsLongResp << 7);
- reg |= (commcontrol.IsInterruptMode << 8);
- reg |= (commcontrol.IsPending << 9);
- reg |= (commcontrol.cmdpath << 10);
- t_mmc0->mmc_Command = reg;
- }
-
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_getresponse */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine returns command index of last command for */
-/* which response received. */
-/* PARAMETERS : */
-/* IN : */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_Command_index command index of last command */
-
-/****************************************************************************/
-
-t_mmc_command_index mmc_getcommandresponse()
-{
- t_mmc_command_index respcommand;
- respcommand = t_mmc0->mmc_RespCommand;
- return respcommand;
-}
-
-/****************************************************************************/
-/* NAME : mmc_getresponse */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine returns response received from the card for */
-/* the last command. */
-/* PARAMETERS : */
-/* IN : t_mmc_response_type Expected response type */
-/* u32 * u32 pointer to store response. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_getresponse(t_mmc_response_type resptype, u32 * response)
-{
- t_mmc_error error;
- if (resptype == MMC_SHORT_RESP)
- *response = (t_mmc0->mmc_Response0);
- else
- {
- *response = t_mmc0->mmc_Response0;
- *(response + 1) = t_mmc0->mmc_Response1;
- *(response + 2) = t_mmc0->mmc_Response2;
- *(response + 3) = t_mmc0->mmc_Response3;
- }
-
- error = MMC_OK;
- return error;
-
-}
-
-/****************************************************************************/
-/* NAME : mmc_setdatapath */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine enables/disables the data path for data transfer.*/
-/* */
-/* PARAMETERS : */
-/* IN : t_mmc_state Specifies the state of the */
-/* data path, whether to enabled or disabled. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_setdatapath(t_mmc_state datapath)
-{
- t_mmc_error error;
- MMC_SET_DATAPATH(t_mmc0->mmc_DataCtrl, datapath);
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_setdatatimeout */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets the data timeout period in card bus */
-/* clock periods */
-/* PARAMETERS : */
-/* IN : u32 Specifies the timeout value of the data path. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_setdatatimeout(u32 datatimeout)
-{
- t_mmc_error error;
- t_mmc0->mmc_DataTimer = datatimeout;
- error = MMC_OK;
- return error;
-
-}
-
-/******************************************************************************/
-/* NAME : mmc_setdatalength */
-/*----------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets the data length (in bytes) for the data */
-/* transfer. */
-/* PARAMETERS : */
-/* IN : u16 Specifies the number of data bytes to be transferred.*/
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/******************************************************************************/
-
-t_mmc_error mmc_setdatalength(u16 datalength)
-{
- t_mmc_error error;
-
- t_mmc0->mmc_DataLength = datalength;
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_setdatablocklength */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets the data block size (in an encoded fashion)*/
-/* for block data transfer. */
-/* PARAMETERS : */
-/* IN : u8 Specifies the data block size for block transfer. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_setdatablocklength(u8 blocksize)
-{
- t_mmc_error error;
- if (blocksize <= MAXBSIZEPOWER)
- {
- MMC_SET_BLOCKSIZE(t_mmc0->mmc_DataCtrl, blocksize);
- error = MMC_OK;
- }
- else
- error = MMC_INVALID_PARAMETER;
- return error;
-
-}
-
-/****************************************************************************/
-/* NAME : mmc_settransferdirection */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: routine sets direction for data transfer, whether */
-/* the transfer is a read or write. */
-/* PARAMETERS : */
-/* IN : t_mmc_transfer_direction the direction for data transfer. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_settransferdirection(t_mmc_transfer_direction transdir)
-{
- t_mmc_error error = MMC_OK;
- MMC_SET_DATADIR(t_mmc0->mmc_DataCtrl, transdir);
- return error;
-}
-
-/******************************************************************************/
-/* NAME : mmc_settransfertype */
-/*----------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets whether data transfer is */
-/* in stream mode or block mode. */
-/* PARAMETERS : */
-/* IN : t_mmc_transfer_type Specifies the transfer type for data transfer. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/******************************************************************************/
-
-t_mmc_error mmc_settransfertype(t_mmc_transfer_type transtype)
-{
- t_mmc_error error = MMC_OK;
- MMC_SET_MODE(t_mmc0->mmc_DataCtrl, transtype);
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_handledma */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine enables or disables data transfer through DMA. */
-/* PARAMETERS : */
-/* IN : t_mmc_state Specifies whether to enable/disable DMA for */
-/* data transfer. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_handledma(t_mmc_state dmastate)
-{
- t_mmc_error error = MMC_OK;
- MMC_SET_DMA(t_mmc0->mmc_DataCtrl, dmastate);
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_getdatacounter */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine returns number of data elements (in bytes) */
-/* yet to be transferred. */
-/* PARAMETERS : */
-/* IN : */
-/* OUT : */
-/* */
-/* RETURN : u16 */
-/****************************************************************************/
-
-u16 mmc_getdatacounter()
-{
- u16 no_of_elements;
- no_of_elements = t_mmc0->mmc_DataCnt;
- return no_of_elements;
-}
-
-/****************************************************************************/
-/* NAME : mmc_selectsdcard */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine selects specific SD card. */
-/* PARAMETERS : */
-/* IN : u8 SD card to select. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_selectsdcard(u8 cardno)
-{
- t_mmc_error error;
-
- if (cardno < 16)
- {
- t_mmc0->mmc_SelectSD = cardno;
- error = MMC_OK;
- }
- else
- error = MMC_REQUEST_NOT_APPLICABLE;
-
- return error;
-
-}
-
-/****************************************************************************/
-/* NAME : mmc_Poweron */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine enquires cards about their operating voltage */
-/* and sets optimal value to supply output voltage. Sends out */
-/* of range cards to inactive states. Also configures */
-/* clock controls. */
-/* PARAMETERS : */
-/* IN : */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_poweron(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 response, one_msec, count = 0, delay;
- t_bool validvoltage, flag = FALSE;
- u32 address_mode = Byte_Mode;
-
- validvoltage = FALSE;
- selected_card = 0;
- no_of_cards = 5;
-
- t_mmc[card_num]->mmc_Power = 0x43; //PowerOn | OpenDrain;
-
- t_mmc[card_num]->mmc_Clock = 0x41FF; //ClkDivInit| ClkEnable | Hwfc_en;//setting clk freq just less than 400KHz
- clockfreq = MCLK / (2 * (ClkDivInit + 1));
- t_mmc[card_num]->mmc_Mask0 &= ~AllInterrupts;
- one_msec = 52000 / ((t_mmc[card_num]->mmc_Power & 0xFF) + 2);
-
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = (GO_IDLE_STATE & ~RespExpected) | CmdPathEnable;
- error = mmc_cmderror(card_num);
- if (error != MMC_OK)
- return error;
-
- /* send CMD8 to verify SD card interface operating condition */
- t_mmc[card_num]->mmc_Argument = Check_Pattern;
- t_mmc[card_num]->mmc_Command = SD_SEND_IF_COND | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp7error(card_num);
- /* IF ERROR IS COMMAND TIMEOUT IT IS MMC CARD */
- if (error == MMC_OK)
- {
- address_mode = Sector_Mode;
- }
- else
- {
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = (GO_IDLE_STATE & ~RespExpected) | CmdPathEnable;
- error = mmc_cmderror(card_num);
- if (error != MMC_OK)
- return error;
- }
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = APP_CMD | RespExpected | CmdPathEnable;
-
-#define barrier() asm volatile("" ::: "memory")
- for (delay = 0; delay < (one_msec * 27); delay++)
- barrier();
-
- error = mmc_cmdresp145error(APP_CMD, card_num);
-
- /* IF ERROR IS COMMAND TIMEOUT IT IS MMC CARD */
- if (MMC_OK == error)
- {
- /*SD CARD */
- /*Send CMD41 SD_APP_APP_OP_COND WITH ARGUMENT 0x00FFC000 */
- printf(" initcard:: Set the SD voltage \n");
- while ((!validvoltage) && (count < 0xFFFF))
- {
- if (flag)
- {
- /*SEND CMD55 APP_CMD with RCA as 0*/
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = APP_CMD | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(APP_CMD, card_num);
- if (error != MMC_OK)
- {
- return (error);
- }
- }
-
- t_mmc[card_num]->mmc_Argument = VoltageWindowSD | address_mode; /* voltage window */
- t_mmc[card_num]->mmc_Command = SD_APP_OP_COND | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp3error(card_num);
- if (MMC_OK != error)
- {
- return (error);
- }
-
- response = t_mmc[card_num]->mmc_Response0;
- validvoltage = (t_bool) (((response >> 31) == 1) ? 1 : 0);
- flag = TRUE;
- count++;
- }
-
- if (count >= 0xFFFF)
- {
- error = MMC_INVALID_VOLTRANGE;
- return (error);
- }
-
- if (Sector_Mode == address_mode)
- {
- printf(" SD high capacity card detected \n");
- }
- else
- {
- printf(" SD card detected \n");
- }
- sd_card = 1;
- }
- else if (MMC_CMD_RSP_TIMEOUT == error)
- {
- /*Send CMD0 GO_IDLE_STATE*/
- printf(" initcard:: Set the MMC voltage \n");
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = (GO_IDLE_STATE & ~RespExpected) | CmdPathEnable;
-
- error = mmc_cmderror(card_num);
- if (MMC_OK != error)
- {
- return (error);
- }
- address_mode = Byte_Mode;
- validvoltage = FALSE;
- response = 0;
-
- /* MMC_CARD */
- while ((!validvoltage) && (count < 0xFFFF))
- {
- t_mmc[card_num]->mmc_Argument = 0xc0ff8000; //VoltageWindowMMC | address_mode;
- t_mmc[card_num]->mmc_Command = SEND_OP_COND | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp3error(card_num);
- if (MMC_OK != error)
- {
- return (error);
- }
-
- for (delay = 0; delay < 1; delay++) ;
-
- response = t_mmc[card_num]->mmc_Response0;
- validvoltage = (t_bool) (((response >> 31) == 1) ? 1 : 0);
- count++;
- }
-
- if (count >= 0xFFFF)
- {
- error = MMC_INVALID_VOLTRANGE;
- return (error);
- }
-
- if (response & Sector_Mode)
- {
- printf(" MMC high capacity card detected \n");
- }
- else
- {
- printf(" EMMC card detected \n");
- }
- mmc_card = 1;
- error = MMC_OK;
- }
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_Poweroff */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine turns the supply output voltage off. */
-/* PARAMETERS : */
-/* IN : */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-t_mmc_error mmc_poweroff(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- t_mmc[card_num]->mmc_Power &= ~PowerOn;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_initializeCards */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine initializes all cards. All cards come into */
-/* standby state. */
-/* PARAMETERS : */
-/* IN : */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_initializeCards(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u16 rca = emmc_rel_addr;
- t_bool card_initialized = FALSE;
-
- if ((t_mmc[card_num]->mmc_Power & PowerOn) == 0x00)
- {
- printf("emmc power failed \n");
- error = MMC_REQUEST_NOT_APPLICABLE;
- return error;
- }
- while (!card_initialized)
- {
- t_mmc[card_num]->mmc_Argument = 0x00000000;
- t_mmc[card_num]->mmc_Command = ALL_SEND_CID | RespExpected | LongResponse | CmdPathEnable;
-
- error = mmc_cmdresp2error(card_num);
- if (MMC_OK != error)
- {
- return (error);
- }
-
- card_array[card_num].CID[0] = t_mmc[card_num]->mmc_Response3;
- card_array[card_num].CID[1] = t_mmc[card_num]->mmc_Response2;
- card_array[card_num].CID[2] = t_mmc[card_num]->mmc_Response1;
- card_array[card_num].CID[3] = t_mmc[card_num]->mmc_Response0;
- if (mmc_card == 1)
- {
- printf("init the MMC Card\n");
- t_mmc[card_num]->mmc_Argument = rca;//rca << 16;
- t_mmc[card_num]->mmc_Command = SET_REL_ADDR | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(SET_REL_ADDR, card_num);
- if (error != MMC_OK)
- {
- printf ("emmc card init response for CMD3 error \n");
- return error;
- }
- }
- else if (sd_card == 1)
- {
- printf("init the SD Card\n");
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = SET_REL_ADDR | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp6error(SET_REL_ADDR, &rca, card_num);
- if (error != MMC_OK)
- {
- printf ("emmc card init response for CMD6 error \n");
- return error;
- }
- }
- card_array[card_num].RCA = rca;
- t_mmc[card_num]->mmc_Argument = rca;//(u32) rca << 16;
- t_mmc[card_num]->mmc_Command = SEND_CSD | RespExpected | LongResponse | CmdPathEnable;
-
- error = mmc_cmdresp2error(card_num);
- if (error != MMC_OK)
- {
- printf("emmc card init response for CMD9 error \n");
- return error;
- }
- card_array[card_num].CSD[0] = t_mmc[card_num]->mmc_Response3;
- card_array[card_num].CSD[1] = t_mmc[card_num]->mmc_Response2;
- card_array[card_num].CSD[2] = t_mmc[card_num]->mmc_Response1;
- card_array[card_num].CSD[3] = t_mmc[card_num]->mmc_Response0;
-
- //rca++;
- error = MMC_OK; //All cards get intialized
- card_initialized = TRUE;
-
- if (card_num != selected_card)
- {
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA;
- t_mmc[card_num]->mmc_Command = SEL_DESEL_CARD
- | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SEL_DESEL_CARD, card_num);
-
- if (error != MMC_OK)
- {
- printf("SEL_DESEL_CARD ::error=0x%x \n", error);
- return error;
- }
- else
- selected_card = card_num;
- }
-
- t_mmc[card_num]->mmc_Argument = (u32) (0x03B70201);
- t_mmc[card_num]->mmc_Command =
- APP_SD_SET_BUSWIDTH | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp2error(card_num);
- if (error != MMC_OK)
- {
- printf("emmc card init response for CMD6 error \n");
- return error;
- }
- }
- t_mmc[card_num]->mmc_Power = 0x3;
- t_mmc[card_num]->mmc_Clock = 0x7500;
-
- /* TODO remove this and use EXT_CSD to determine it */
- if (mmc_card == 1 && t_mmc[card_num] == 0x80005000)
- card_array[card_num].blockaddressed = 0;
- else
- card_array[card_num].blockaddressed = 1;
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_setdevicemode */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine sets device mode whether to operate in Polling,*/
-/* Interrupt, dma mode. */
-/* PARAMETERS : */
-/* IN : t_mmc_device_mode mode to for further transmission. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_setdevicemode(t_mmc_device_mode mode)
-{
- t_mmc_error error;
-
- switch (mode)
- {
- case POLLING_MODE:
- device_mode = POLLING_MODE;
- break;
- case INTERRUPT_MODE:
- device_mode = INTERRUPT_MODE;
- break;
- case DMA_MODE:
- device_mode = DMA_MODE;
- break;
- default:
- error = MMC_INVALID_PARAMETER;
- return error;
- }
-
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_readbytes */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine allows to read bytes from specified address */
-/* in a card */
-/* PARAMETERS : */
-/* IN : u8 cardno: card to access */
-/* u32 addr : address from where to start reading */
-/* u16 no_of_bytes: no. of bytes to read */
-/* OUT : u32* readbuff: buffer to store data */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_readbytes(u8 card_num, u32 addr, u32 * readbuff,u16 no_of_bytes)
-{
- t_mmc_error error = MMC_OK;
- u32 i;
- u32 timeout = 0;
- u32 *tempbuff = readbuff;
-
- total_no_of_bytes = 0;
-
- t_mmc0->mmc_DataCtrl = AllZero;
-
- if ((card_num > no_of_cards) || (card_num == 0))
- {
- error = MMC_INVALID_PARAMETER;
- return error;
- }
-
- /* send command for selecting the card */
- if (card_num != selected_card)
- {
- t_mmc0->mmc_Argument = card_array[card_num].RCA;//card_array[card_num - 1].RCA << 16;
- t_mmc0->mmc_Command = SEL_DESEL_CARD | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_REL_ADDR, card_num);
- if (error != MMC_OK)
- return error;
- else
- selected_card = card_num;
- }
-
- /* now depending on parameter no_of_bytes, send command READ_DAT_UNTIL_STOP */
-
- if (no_of_bytes == 0) // this means open-ended stream read,until STOP_TRANSMISSION follows
- {
- if (device_mode != INTERRUPT_MODE)
- return MMC_REQUEST_NOT_APPLICABLE;
-
- total_no_of_bytes = 65532;
-
- t_mmc0->mmc_DataLength = 65532;
-
- t_mmc0->mmc_DataTimer = 0xefffffff;
-
- t_mmc0->mmc_DataCtrl = ReadDir | StreamMode | DataPathEnable;
-
- dest_buffer = readbuff;
-
- t_mmc0->mmc_Clock = (t_mmc0->mmc_Clock & 0xFFFFFF00) | 0x0000000B;
-
- t_mmc0->mmc_Argument = addr >> 9;
- t_mmc0->mmc_Command = READ_DAT_UNTIL_STOP | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(READ_DAT_UNTIL_STOP, card_num);
- if (error != MMC_OK)
- return error;
-
- t_mmc0->mmc_Mask0 = DataCrcFail | DataTimeOut | RxFifoHalfFull | RxOverrun;
- }
- else if (no_of_bytes > 0)
- {
- total_no_of_bytes = no_of_bytes;
-
- t_mmc0->mmc_DataLength = no_of_bytes;
-
- t_mmc0->mmc_DataTimer = 0xefffffff;
-
- t_mmc0->mmc_DataCtrl = ReadDir | StreamMode | DataPathEnable;
-
- dest_buffer = readbuff;
-
- t_mmc0->mmc_Clock = (t_mmc0->mmc_Clock & 0xFFFFFF00) | 0x0000000B;
-
- t_mmc0->mmc_Argument = addr >> 9;
- t_mmc0->mmc_Command = READ_DAT_UNTIL_STOP | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(READ_DAT_UNTIL_STOP, card_num);
-
- if (error != MMC_OK)
- return error;
-
- if (device_mode == POLLING_MODE)
- {
-
- timeout = 0xffffffff;
-
- while ((timeout > 0) && !(t_mmc0->mmc_Status & (DataCrcFail | DataTimeOut | DataEnd)))
- {
- timeout--;
- if (t_mmc0->mmc_Status & RxFifoHalfFull)
- {
- for (i = 0; i < 8; i++)
- *(tempbuff + i) = t_mmc0->mmc_Fifo;
- tempbuff += 8;
- }
-
- }
-
- if ((timeout == 0) || (t_mmc0->mmc_Status & DataTimeOut))
- {
- t_mmc0->mmc_Clear |= DataTimeOut;
- error = MMC_DATA_TIMEOUT;
- transfer_error = MMC_DATA_TIMEOUT;
- return error;
- }
- else if (t_mmc0->mmc_Status & DataCrcFail)
- {
- t_mmc0->mmc_Clear |= DataCrcFail;
- error = MMC_DATA_CRC_FAIL;
- transfer_error = MMC_DATA_CRC_FAIL;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags
-
- while (t_mmc0->mmc_Status & RxDataAvlbl)
- {
- *tempbuff = t_mmc0->mmc_Fifo;
- tempbuff++;
- }
-
- t_mmc0->mmc_Argument = 0x00000000;
- t_mmc0->mmc_Command = STOP_TRANSMISSION | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(STOP_TRANSMISSION, card_num);
-
- transfer_error = error;
- if (error != MMC_OK)
- return error;
-
- }
-
- else if (device_mode == INTERRUPT_MODE)
- t_mmc0->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | RxFifoHalfFull | RxOverrun;
-
- else if (device_mode == DMA_MODE)
- {
- t_mmc0->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | RxOverrun;
- t_mmc0->mmc_DataCtrl |= DMAEnab;
- }
- }
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_writebytes */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine allows to write bytes starting from a specified*/
-/* address in a card */
-/* PARAMETERS : */
-/* IN : u8 cardno: card to access */
-/* u32 addr : address where to start writing */
-/* u16 no_of_bytes: no. of bytes to write */
-/* OUT : u32* writebuff: source buffer */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_writebytes(u8 card_num, u32 addr, u32 * writebuff, u16 no_of_bytes)
-{
- t_mmc_error error;
- u32 timeout = 0;
- u32 *tempbuff = writebuff;
- u32 i, j, bytes_transferred = 0;
- u8 cardstate;
-
- total_no_of_bytes = 0;
-
- t_mmc0->mmc_DataCtrl = AllZero;
-
- if ((card_num > no_of_cards) || (card_num == 0))
- {
- error = MMC_INVALID_PARAMETER;
- return error;
- }
- /* send command for selecting the card */
-
- if (card_num != selected_card)
- {
- t_mmc0->mmc_Argument = card_array[card_num].RCA;//card_array[card_num - 1].RCA << 16;
- t_mmc0->mmc_Command = SEL_DESEL_CARD | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SEL_DESEL_CARD, card_num);
-
- if (error != MMC_OK)
- return error;
- else
- selected_card = card_num;
- }
-
- /* now depending on parameter no_of_bytes, send command WRITE_DAT_UNTIL_STOP */
-
- if (no_of_bytes == 0) // this means open-ended stream read,until STOP_TRANSMISSION follows
- {
- if (device_mode != INTERRUPT_MODE)
- return MMC_REQUEST_NOT_APPLICABLE;
-
- t_mmc0->mmc_DataTimer = 0xefffffff;
-
- total_no_of_bytes = 65532;
-
- t_mmc0->mmc_DataLength = 65532;
-
- source_buffer = writebuff;
-
- t_mmc0->mmc_Clock = (t_mmc0->mmc_Clock & 0xFFFFFF00) | 0x00000031;
-
- t_mmc0->mmc_Argument = addr >> 9;
- t_mmc0->mmc_Command = WRITE_DAT_UNTIL_STOP | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(WRITE_DAT_UNTIL_STOP, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc0->mmc_DataCtrl = (StreamMode & ~ReadDir) | DataPathEnable;
-
- t_mmc0->mmc_Mask0 = DataCrcFail | DataTimeOut | TxFifoHalfEmpty | TxUnderrun;
-
- /*Now the card will send data thru DMA to the destination buffer.CRC/TimeOut error will
- be handled in the interrupt handler*/
- }
- else if (no_of_bytes > 0)
- {
- total_no_of_bytes = no_of_bytes;
-
- t_mmc0->mmc_DataLength = no_of_bytes;
-
- t_mmc0->mmc_DataTimer = 0xefffffff;
-
- source_buffer = writebuff;
-
- t_mmc0->mmc_Argument = addr >> 9;
- t_mmc0->mmc_Command = WRITE_DAT_UNTIL_STOP | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(WRITE_DAT_UNTIL_STOP, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc0->mmc_DataCtrl = (StreamMode & ~ReadDir) | DataPathEnable;
-
- if (device_mode == POLLING_MODE)
- {
- timeout = 0xefffffff;
-
- while ((timeout > 0) && !(t_mmc0->mmc_Status & (DataCrcFail | DataTimeOut | DataEnd)))
- {
- timeout--;
- if (t_mmc0->mmc_Status & TxFifoHalfEmpty)
- {
- if ((total_no_of_bytes - bytes_transferred) < 32)
- {
- j = ((total_no_of_bytes - bytes_transferred) % 4 == 0) ?
- ((total_no_of_bytes - bytes_transferred) / 4)
- : ((total_no_of_bytes - bytes_transferred) / 4 +1);
-
- for (i = 0; i < j; i++, tempbuff++,bytes_transferred += 4)
- t_mmc0->mmc_Fifo = *tempbuff;
-
- }
- else
- {
- for (i = 0; i < 8; i++)
- t_mmc0->mmc_Fifo = *(tempbuff + i);
- tempbuff += 8;
- bytes_transferred += 32;
- }
- }
- }
-
- if ((timeout == 0) || (t_mmc0->mmc_Status & DataTimeOut))
- {
- t_mmc0->mmc_Clear |= DataTimeOut;
- transfer_error = error = MMC_DATA_TIMEOUT;
- return error;
- }
- else if (t_mmc0->mmc_Status & DataCrcFail)
- {
- t_mmc0->mmc_Clear |= DataCrcFail;
- transfer_error = error = MMC_DATA_CRC_FAIL;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags
-
- mmc_iscardprogramming(card_num, &cardstate);
- while ((cardstate == 7) || (cardstate == 6))
- mmc_iscardprogramming(card_num, &cardstate);
-
- t_mmc0->mmc_Argument = 0x00000000;
- t_mmc0->mmc_Command = STOP_TRANSMISSION | RespExpected | CmdPathEnable;
-
- transfer_error = error = mmc_cmdresp145error(STOP_TRANSMISSION, card_num);
-
- if (error != MMC_OK)
- return error;
-
- }
-
- else if (device_mode == INTERRUPT_MODE)
-
- t_mmc0->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | TxFifoHalfEmpty | TxUnderrun;
-
- else if (device_mode == DMA_MODE)
- {
- t_mmc0->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | TxUnderrun;
- t_mmc0->mmc_DataCtrl |= DMAEnab;
- }
-
- }
- error = MMC_OK;
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_readblocks */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine allows to read blocks from a specified */
-/* address in a card */
-/* PARAMETERS : */
-/* IN : u8 cardno: card to access */
-/* u32 addr : address from where to start reading */
-/* u16 blocksize : size of block in bytes */
-/* u16 no_of_blocks: no. of blocks to read */
-/* OUT : u32* readbuff: source buffer */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_readblocks(u8 card_num, u32 addr, u32 * readbuff, u16 blocksize, u16 no_of_blocks)
-{
- t_mmc_error error = MMC_OK;
- u32 i;
- u32 timeout = 0;
- u8 power;
- u32 *tempbuff = readbuff;
-
- total_no_of_bytes = 0;
-
- t_mmc[card_num]->mmc_DataCtrl = AllZero;
-
- /* send command for selecting the card */
- if ((card_num > no_of_cards) || (card_num == 0))
- {
- error = MMC_INVALID_PARAMETER;
- return error;
- }
- if (card_num != selected_card)
- {
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA;//0x1 << 16; //card_array[cardno - 1].RCA << 16;
- t_mmc[card_num]->mmc_Command = SEL_DESEL_CARD | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SEL_DESEL_CARD, card_num);
-
- if (error != MMC_OK)
- {
- printf("SEL_DESEL_CARD ::error=0x%x \n", error);
- return error;
- }
- else
- selected_card = card_num;
- }
-
- if (t_mmc[card_num]->mmc_Response0 & 0x02000000)
- return MMC_LOCK_UNLOCK_FAILED;
-
- /* now depending on parameter no_of_blocks, send command READ_DAT_UNTIL_STOP */
-
- //set the block size,both on controller and card
-
- if ((blocksize > 0) && (blocksize <= 2048) && ((blocksize & (blocksize - 1)) == 0))
- {
-
- power = convert_from_bytes_to_power_of_two(blocksize);
- t_mmc[card_num]->mmc_DataCtrl = power << 4;
-
- t_mmc[card_num]->mmc_Argument = (u32) blocksize;
- t_mmc[card_num]->mmc_Command = SET_BLOCKLEN | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_BLOCKLEN, card_num);
-
- if (error != MMC_OK)
- {
- printf("SET_BLOCKLEN ::error=0x%x \n", error);
- return error;
- }
- }
- else
- {
- printf("SET_BLOCKLEN ::error set proper block len\n");
- error = MMC_INVALID_PARAMETER;
- return error;
- }
-
- if (no_of_blocks == 0) // this means open-ended block read,until STOP_TRANSMISSION follows
- {
-
- if (device_mode != INTERRUPT_MODE)
- return MMC_REQUEST_NOT_APPLICABLE;
-
- t_mmc[card_num]->mmc_DataTimer = 0xefffffff;
-
- t_mmc[card_num]->mmc_DataLength = (65535 / blocksize) * blocksize;
-
- total_no_of_bytes = (65535 / blocksize) * blocksize;
-
- t_mmc[card_num]->mmc_Argument = (65535 / blocksize);
- t_mmc[card_num]->mmc_Command = SET_BLOCK_COUNT | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_BLOCK_COUNT, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc[card_num]->mmc_DataCtrl |= (ReadDir & ~StreamMode) | DataPathEnable;
-
- dest_buffer = readbuff;
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (addr >> 9) : addr;
- t_mmc[card_num]->mmc_Command = READ_MULT_BLOCK | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(READ_MULT_BLOCK, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | RxFifoHalfFull | RxOverrun;
-
- /*Now the card will send data thru DMA to the destination buffer.CRC/TimeOut error will
- be handled in the interrupt handler*/
-
- }
- else if (no_of_blocks == 1)
- {
- total_no_of_bytes = blocksize;
-
- t_mmc[card_num]->mmc_DataLength = blocksize;
-
- t_mmc[card_num]->mmc_DataTimer = 0x0fffffff;
-
- t_mmc[card_num]->mmc_DataCtrl |= (ReadDir & ~StreamMode) | DataPathEnable;
-
- dest_buffer = readbuff;
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (addr >> 9) : addr;
- t_mmc[card_num]->mmc_Command = READ_SINGLE_BLOCK | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(READ_SINGLE_BLOCK, card_num);
-
- if (error != MMC_OK)
- {
- printf("READ_SINGLE_BLOCK ::error=0x%x \n", error);
- return error;
- }
- if (device_mode == POLLING_MODE)
- {
-
- timeout = 0xefffffff;
-
- while ((timeout > 0) && !(t_mmc[card_num]->mmc_Status & (RxOverrun | DataCrcFail |
- DataTimeOut | DataBlockEnd)))
- {
- timeout--;
- if (t_mmc[card_num]->mmc_Status & RxFifoHalfFull)
- {
- for (i = 0; i < 8; i++)
- {
- *(tempbuff + i) = t_mmc[card_num]->mmc_Fifo;
- }
- tempbuff += 8;
- }
-
- }
-
- if ((timeout == 0)|| (t_mmc[card_num]->mmc_Status & DataTimeOut))
- {
- t_mmc[card_num]->mmc_Clear |= DataTimeOut;
- transfer_error = error = MMC_DATA_TIMEOUT;
- printf("mmc_readblocks::1 MMC_DATA_TIMEOUT \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & DataCrcFail)
- {
- t_mmc[card_num]->mmc_Clear |= DataCrcFail;
- transfer_error = error = MMC_DATA_CRC_FAIL;
- printf("mmc_readblocks::1 MMC_DATA_CRC_FAIL \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & RxOverrun)
- {
- t_mmc[card_num]->mmc_Clear |= RxOverrun;
- transfer_error = error = MMC_RX_OVERRUN;
- printf("mmc_readblocks::1 MMC_RX_OVERRUN \n");
- return error;
- }
-
- while (t_mmc[card_num]->mmc_Status & RxDataAvlbl)
- {
- *tempbuff = t_mmc[card_num]->mmc_Fifo;
- tempbuff++;
- }
- transfer_error = error;
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags; //clear all the static status flags
- }
-
- else if (device_mode == INTERRUPT_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | RxFifoHalfFull | RxOverrun;
- }
- else if (device_mode == DMA_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | RxOverrun;
- t_mmc[card_num]->mmc_DataCtrl |= DMAEnab;
- }
-
- }
- else if (no_of_blocks > 1)
- {
- // set the block count,both for the controller and the card
- total_no_of_bytes = no_of_blocks * blocksize;
-
- t_mmc[card_num]->mmc_DataLength = no_of_blocks * blocksize;
-
- t_mmc[card_num]->mmc_Argument = (u32) no_of_blocks;
- t_mmc[card_num]->mmc_Command = SET_BLOCK_COUNT | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_BLOCK_COUNT, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc[card_num]->mmc_DataTimer = 0xefffffff;
-
- t_mmc[card_num]->mmc_DataCtrl |= (ReadDir & ~StreamMode) | DataPathEnable;
-
- dest_buffer = readbuff;
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (addr >> 9) : addr;
- t_mmc[card_num]->mmc_Command = READ_MULT_BLOCK | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(READ_MULT_BLOCK, card_num);
- if (error != MMC_OK)
- return error;
-
- if (device_mode == POLLING_MODE)
- {
- timeout = 0xefffffff;
- while ((timeout > 0)&& !(t_mmc[card_num]->mmc_Status & (RxOverrun | DataCrcFail |DataTimeOut | DataEnd)))
- {
- timeout--;
- if (t_mmc[card_num]->mmc_Status & RxFifoHalfFull)
- {
- for (i = 0; i < 8; i++)
- {
- *(tempbuff + i) = t_mmc[card_num]->mmc_Fifo;
- }
- tempbuff += 8;
- }
- }
-
- if ((timeout == 0) || (t_mmc[card_num]->mmc_Status & DataTimeOut))
- {
- t_mmc[card_num]->mmc_Clear |= DataTimeOut;
- transfer_error = error = MMC_DATA_TIMEOUT;
- return error;
-
- }
- else if (t_mmc[card_num]->mmc_Status & DataCrcFail)
- {
- t_mmc[card_num]->mmc_Clear |= DataCrcFail;
- transfer_error = error = MMC_DATA_CRC_FAIL;
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & RxOverrun)
- {
- t_mmc[card_num]->mmc_Clear |= RxOverrun;
- transfer_error = error = MMC_RX_OVERRUN;
- return error;
- }
-
- while (t_mmc[card_num]->mmc_Status & RxDataAvlbl)
- {
- *tempbuff = t_mmc[card_num]->mmc_Fifo;
- tempbuff++;
- }
- transfer_error = error;
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags; //clear all the static status flags
- }
-
- else if (device_mode == INTERRUPT_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | RxFifoHalfFull | RxOverrun;
- }
- else if (device_mode == DMA_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | RxOverrun;
- t_mmc[card_num]->mmc_DataCtrl |= DMAEnab;
- }
- }
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_writeblocks */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine allows to write blocks starting from a */
-/* specified address in a card */
-/* PARAMETERS : */
-/* IN : u8 cardno: card to access */
-/* u32 addr : address from where to start writing */
-/* u16 blocksize : size of block in bytes */
-/* u16 no_of_blocks: no. of blocks to write */
-/* OUT : u32* writebuff: source buffer */
-/* */
-/* RETURN : t_mmc_error */
-/****************************************************************************/
-
-t_mmc_error mmc_writeblocks(u8 card_num, u32 addr, u32 * writebuff,
- u16 blocksize, u16 no_of_blocks)
-{
- t_mmc_error error = MMC_OK;
- u32 count, rest_words;
- u8 power, cardstate;
- u32 timeout = 0;
- u32 *tempbuff = writebuff;
- u32 bytes_transferred = 0;
- u32 card_status;
-
- if (NULL == writebuff)
- {
- error = MMC_INVALID_PARAMETER;
- return (error);
- }
-
- total_no_of_bytes = 0;
-
- t_mmc[card_num]->mmc_DataCtrl = AllZero;
-
- /* send command for selecting the card */
- if ((card_num > no_of_cards) || (card_num == 0))
- {
- error = MMC_INVALID_PARAMETER;
- return error;
- }
- if (card_num != selected_card)
- {
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA; //card_array[cardno - 1].RCA << 16;
- t_mmc[card_num]->mmc_Command = SEL_DESEL_CARD | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SEL_DESEL_CARD, card_num);
-
- if (error != MMC_OK)
- return error;
- else
- selected_card = card_num;
- }
-
- if (t_mmc[card_num]->mmc_Response0 & R1_CARD_IS_LOCKED)
- return MMC_LOCK_UNLOCK_FAILED;
-
- /* now depending on parameter no_of_blocks, send command READ_DAT_UNTIL_STOP */
-
- //set the block size,both on controller and card
-
- if ((blocksize > 0) && (blocksize <= 2048)
- && (((blocksize & (blocksize - 1)) == 0)))
- {
- power = convert_from_bytes_to_power_of_two(blocksize);
- t_mmc[card_num]->mmc_DataCtrl = power << 4;
-
- t_mmc[card_num]->mmc_Argument = (u32) blocksize;
- t_mmc[card_num]->mmc_Command = SET_BLOCKLEN | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_BLOCKLEN, card_num);
-
- if (error != MMC_OK)
- return error;
-
- }
- else
- {
- printf(" mmc_writeblocks::bad block size \n");
- error = MMC_INVALID_PARAMETER;
- return error;
- }
-
- if (no_of_blocks == 0) // this means open-ended block read,until STOP_TRANSMISSION follows
- {
- if (device_mode != INTERRUPT_MODE)
- return MMC_REQUEST_NOT_APPLICABLE;
-
- t_mmc[card_num]->mmc_DataTimer = 0xefffffff;
-
- t_mmc[card_num]->mmc_DataLength = (65535 / blocksize) * blocksize;
-
- total_no_of_bytes = (65535 / blocksize) * blocksize;
-
- t_mmc[card_num]->mmc_Argument = (65535 / blocksize);
- t_mmc[card_num]->mmc_Command = SET_BLOCK_COUNT | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_BLOCK_COUNT, card_num);
-
- if (error != MMC_OK)
- return error;
-
- source_buffer = writebuff;
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (addr >> 9) : addr;
- t_mmc[card_num]->mmc_Command = WRITE_MULT_BLOCK | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(WRITE_MULT_BLOCK, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc[card_num]->mmc_DataCtrl |= DataPathEnable & ~(ReadDir | StreamMode);
-
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | TxFifoHalfEmpty | TxUnderrun;
-
- /*Now the card will send data thru DMA to the destination buffer.CRC/TimeOut error will
- be handled in the interrupt handler*/
-
- }
- else if (no_of_blocks == 1)
- {
- total_no_of_bytes = blocksize;
-
- t_mmc[card_num]->mmc_DataLength = blocksize;
-
- t_mmc[card_num]->mmc_DataTimer = 0xefffffff;
-
- source_buffer = writebuff;
-
- /*Wait till card is ready for data Added*/
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA; //card_array[cardno - 1].RCA << 16;
- t_mmc[card_num]->mmc_Command = SEND_STATUS | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(SEND_STATUS, card_num);
-
- if (error != MMC_OK)
- return error;
-
- card_status = t_mmc[card_num]->mmc_Response0;
- timeout = 0xefffffff;
-
- while ((0 == (card_status & 0x00000100)) && (timeout > 0))
- {
- timeout--;
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA;//0x1 << 16;
- t_mmc[card_num]->mmc_Command = SEND_STATUS | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SEND_STATUS, card_num);
-
- if (error != MMC_OK)
- return error;
- card_status = t_mmc[card_num]->mmc_Response0;
- }
- if (timeout == 0)
- {
- return (MMC_DATA_TIMEOUT);
- }
-
- /*Till here*/
- /*SEND CMD24 WRITE_SINGLE_BLOCK */
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (addr >> 9) : addr;
- t_mmc[card_num]->mmc_Command = WRITE_SINGLE_BLOCK | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(WRITE_SINGLE_BLOCK, card_num);
- if (error != MMC_OK)
- return error;
- t_mmc[card_num]->mmc_DataCtrl |= DataPathEnable & ~(ReadDir | StreamMode);
-
- if (device_mode == POLLING_MODE)
- {
-
- while (!(t_mmc[card_num]->mmc_Status & (DataBlockEnd | TxUnderrun | DataCrcFail | DataTimeOut)))
- {
-
- if (t_mmc[card_num]-> mmc_Status & TxFifoHalfEmpty)
- {
- if ((total_no_of_bytes - bytes_transferred) < 32)
- {
- rest_words = ((total_no_of_bytes - bytes_transferred) % 4 == 0) ?
- ((total_no_of_bytes - bytes_transferred) / 4)
- : ((total_no_of_bytes - bytes_transferred) / 4 +1);
-
- for (count = 0; count < rest_words; count++, tempbuff++, bytes_transferred += 4)
- t_mmc[card_num]-> mmc_Fifo = *tempbuff;
-
- }
- else
- {
- for (count = 0; count < 8; count++)
- {
- t_mmc[card_num]->mmc_Fifo = *(tempbuff + count);
- }
- tempbuff += 8;
- bytes_transferred += 32;
- }
- }
- }
-
- if ((timeout == 0) || (t_mmc[card_num]->mmc_Status & DataTimeOut))
- {
- t_mmc[card_num]->mmc_Clear |= DataTimeOut;
- transfer_error = error = MMC_DATA_TIMEOUT;
- printf(" MMC_DATA_TIMEOUT error \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & DataCrcFail)
- {
- t_mmc[card_num]->mmc_Clear |= DataCrcFail;
- transfer_error = error = MMC_DATA_CRC_FAIL;
- printf(" MMC_DATA_CRC_FAIL error \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & TxUnderrun)
- {
- t_mmc[card_num]->mmc_Clear |= TxUnderrun;
- transfer_error = error = MMC_TX_UNDERRUN;
- printf(" MMC_TX_UNDERRUN underrun error \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & StartBitError)
- {
- t_mmc[card_num]->mmc_Clear |= StartBitError;
- transfer_error = error = MMC_START_BIT_ERR;
- printf(" MMC_START_BIT_ERR start bit error \n");
- return error;
- }
- //clear all the static status flags
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags;
- transfer_error = error;
-
- error = mmc_iscardprogramming(card_num, &cardstate);
- while (error == MMC_OK && ((cardstate == 7) || (cardstate == 6)))
- error = mmc_iscardprogramming(card_num, &cardstate);
- }
-
- else if (device_mode == INTERRUPT_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | TxFifoHalfEmpty | TxUnderrun;
- }
- else if (device_mode == DMA_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | TxUnderrun;
- t_mmc[card_num]->mmc_DataCtrl |= DMAEnab;
- }
-
- }
- else if (no_of_blocks > 1)
- {
- // set the block count,both for the controller and the card
- if (no_of_blocks * blocksize > 0x01FFFFFF)
- {
- error = MMC_INVALID_PARAMETER;
- return (error);
- }
-
- total_no_of_bytes = no_of_blocks * blocksize;
-
- t_mmc[card_num]->mmc_DataLength = (u32) (no_of_blocks * blocksize);
-
- t_mmc[card_num]->mmc_Argument = (u32) no_of_blocks;
- t_mmc[card_num]->mmc_Command = SET_BLOCK_COUNT | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SET_BLOCK_COUNT, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc[card_num]->mmc_DataTimer = 0xefffffff;
-
- source_buffer = writebuff;
-
- /*SEND CMD25 WRITE_MULT_BLOCK with argument data address*/
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (addr >> 9) : addr;
- t_mmc[card_num]->mmc_Command = WRITE_MULT_BLOCK | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(WRITE_MULT_BLOCK, card_num);
-
- if (error != MMC_OK)
- return error;
-
- t_mmc[card_num]->mmc_DataCtrl |= DataPathEnable & ~(ReadDir | StreamMode);
-
- if (device_mode == POLLING_MODE)
- {
- timeout = 0xefffffff;
-
- while ((timeout > 0) && !(t_mmc[card_num]->mmc_Status & (TxUnderrun | DataCrcFail |
- DataTimeOut | DataEnd | StartBitError)))
- {
- timeout--;
- if (t_mmc[card_num]-> mmc_Status & TxFifoHalfEmpty)
- {
- if ((total_no_of_bytes - bytes_transferred) < 32)
- {
- rest_words = ((total_no_of_bytes - bytes_transferred) % 4 == 0) ?
- ((total_no_of_bytes - bytes_transferred) /4)
- : ((total_no_of_bytes - bytes_transferred) / 4 +1);
-
- for (count = 0; count < rest_words; count++, tempbuff++,bytes_transferred += 4)
- t_mmc[card_num]-> mmc_Fifo = *tempbuff;
-
- }
- else
- {
- for (count = 0; count < 8; count++)
- {
- t_mmc[card_num]-> mmc_Fifo = *(tempbuff + count);
- }
- tempbuff += 8;
- bytes_transferred += 32;
- }
- }
-
- }
-
- if ((timeout == 0) || (t_mmc[card_num]->mmc_Status & DataTimeOut))
- {
- t_mmc[card_num]->mmc_Clear |= DataTimeOut;
- transfer_error = error = MMC_DATA_TIMEOUT;
- printf(" MMC_DATA_TIMEOUT start bit error \n");
- return error;
-
- }
- else if (t_mmc[card_num]->mmc_Status & DataCrcFail)
- {
- t_mmc[card_num]->mmc_Clear |= DataCrcFail;
- transfer_error = error = MMC_DATA_CRC_FAIL;
- printf(" MMC_DATA_CRC_FAIL start bit error \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & TxUnderrun)
- {
- t_mmc[card_num]->mmc_Clear |= TxUnderrun;
- transfer_error = error = MMC_TX_UNDERRUN;
- printf(" MMC_TX_UNDERRUN start bit error \n");
- return error;
- }
- else if (t_mmc[card_num]->mmc_Status & StartBitError)
- {
- t_mmc[card_num]->mmc_Clear |= StartBitError;
- transfer_error = error = MMC_START_BIT_ERR;
- printf(" MMC_START_BIT_ERR start bit error \n");
- return error;
- }
-
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags; //clear all the static status flags
- transfer_error = error;
- error = mmc_iscardprogramming(card_num, &cardstate);
- while ((MMC_OK == error) && ((cardstate == 7) || (cardstate == 6)))
- error = mmc_iscardprogramming(card_num, &cardstate);
- }
- else if (device_mode == INTERRUPT_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd |TxFifoHalfEmpty | TxUnderrun;
- }
- else if (device_mode == DMA_MODE)
- {
- t_mmc[card_num]->mmc_Mask0 = DataCrcFail | DataTimeOut | DataEnd | TxUnderrun;
- t_mmc[card_num]->mmc_DataCtrl |= DMAEnab;
- }
-
- }
-
- return error;
-}
-
-/****************************************************************************/
-/* NAME : mmc_gettransferstate() */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine */
-/* PARAMETERS : */
-/* */
-/* RETURN : t_mmc_transfer_state */
-/****************************************************************************/
-
-t_mmc_transfer_state mmc_gettransferstate()
-{
- if (t_mmc0->mmc_Status & (TxActive | RxActive))
- return TRANSFER_IN_PROGRESS;
- else
- return NO_TRANSFER;
-}
-
-/****************************************************************************/
-/* NAME : mmc_erase */
-/*--------------------------------------------------------------------------*/
-/* DESCRIPTION: This routine allows to erase memory area specified for the */
-/* given card. */
-/* PARAMETERS : */
-/* IN : u8 Cardno. to access */
-/* u32 start address for erase. */
-/* u32 Last address for erase. */
-/* OUT : */
-/* */
-/* RETURN : t_mmc_error */
-
-/****************************************************************************/
-
-t_mmc_error mmc_erase(u8 card_num, u32 StartAddr, u32 EndAddr)
-{
- t_mmc_error error;
- u32 response;
- u8 cardstate;
- u32 delay, max_delay;
-
- if ((card_num > no_of_cards) || (card_num == 0))
- {
- printf("mmc_erase:: card no=%d no_of_cards=%d failed \n",card_num, no_of_cards);
- error = MMC_INVALID_PARAMETER;
- return error;
- }
- max_delay = 52000 / ((t_mmc[card_num]->mmc_Clock & 0xFF) + 2);
-
- /* send command for selecting the card */
-
- if (card_num != selected_card)
- {
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA; //card_array[cardno - 1].RCA << 16;
- t_mmc[card_num]->mmc_Command = SEL_DESEL_CARD | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(SEL_DESEL_CARD, card_num);
- if (error != MMC_OK)
- return error;
- else
- selected_card = card_num;
- }
-
- if (t_mmc[card_num]->mmc_Response0 & R1_CARD_IS_LOCKED)
- {
- error = MMC_LOCK_UNLOCK_FAILED;
- return (error);
- }
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (StartAddr >> 9) : StartAddr;
- t_mmc[card_num]->mmc_Command = ERASE_GRP_START | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(ERASE_GRP_START, card_num);
- if (error != MMC_OK)
- {
- printf("mmc_erase:: erase start CMD35 failed \n");
- return error;
- }
- response = t_mmc[card_num]->mmc_Response0;
-
- if (response & (R1_OUT_OF_RANGE | R1_ERASE_PARAM))
- {
- printf("mmc_erase:: erase start CMD35 R1_OUT_OF_RANGE \n");
- error = MMC_BAD_ERASE_PARAM;
- return error;
- }
-
- if (response & R1_ERASE_SEQ_ERROR)
- {
- printf("mmc_erase:: erase start CMD35 R1_ERASE_SEQ_ERROR \n");
- error = MMC_ERASE_SEQ_ERR;
- return error;
- }
-
- if (response & (R1_CARD_IS_LOCKED | R1_LOCK_UNLOCK_FAILED))
- {
- printf("mmc_erase:: erase start CMD35 R1_CARD_IS_LOCKED \n");
- error = MMC_LOCK_UNLOCK_FAILED;
- return error;
- }
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].blockaddressed ? (EndAddr >> 9) : EndAddr;
- t_mmc[card_num]->mmc_Command = ERASE_GRP_END | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(ERASE_GRP_END, card_num);
- if (error != MMC_OK)
- {
- printf("mmc_erase:: erase end CMD36 failed \n");
- return error;
- }
- response = t_mmc[card_num]->mmc_Response0;
-
- if (response & (R1_OUT_OF_RANGE | R1_ERASE_PARAM))
- {
- printf("mmc_erase:: erase end R1_OUT_OF_RANGE \n");
- error = MMC_BAD_ERASE_PARAM;
- return error;
- }
-
- if (response & R1_ERASE_SEQ_ERROR)
- {
- printf("mmc_erase:: erase end R1_ERASE_SEQ_ERROR \n");
- error = MMC_ERASE_SEQ_ERR;
- return error;
- }
-
- if (response & (R1_CARD_IS_LOCKED | R1_LOCK_UNLOCK_FAILED))
- {
- printf("mmc_erase:: erase end R1_CARD_IS_LOCKED\n");
- error = MMC_LOCK_UNLOCK_FAILED;
- return error;
- }
-
- t_mmc[card_num]->mmc_Argument = 0;
- t_mmc[card_num]->mmc_Command = ERASE | RespExpected | CmdPathEnable;
- error = mmc_cmdresp145error(ERASE, card_num);
- if (error != MMC_OK)
- {
- printf("mmc_erase:: erase CMD38 failed \n");
- return error;
- }
- response = t_mmc[card_num]->mmc_Response0;
- if (response & R1_ERASE_SEQ_ERROR)
- {
- printf("mmc_erase:: erase R1_ERASE_SEQ_ERROR \n");
- error = MMC_ERASE_SEQ_ERR;
- return error;
- }
-
- if (response & (R1_CARD_IS_LOCKED | R1_LOCK_UNLOCK_FAILED))
- {
- printf("mmc_erase:: erase R1_CARD_IS_LOCKED \n");
- error = MMC_LOCK_UNLOCK_FAILED;
- return error;
- }
-
- if (response & R1_WP_ERASE_SKIP)
- {
- printf("mmc_erase:: erase R1_WP_ERASE_SKIP \n");
- error = MMC_WRITE_PROT_VIOLATION;
- return error;
- }
- for (delay = 0; delay < (max_delay * 3); delay++) ;
-
- mmc_iscardprogramming(card_num, &cardstate);
- while ((MMC_OK == error) && ((cardstate == 7) || (cardstate == 6)))
- mmc_iscardprogramming(card_num, &cardstate);
-
- error = MMC_OK;
- return error;
-}
-
-t_mmc_error mmc_cmderror(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 timeout;
-
- timeout = 100000;
- while ((timeout > 0) && !(t_mmc[card_num]->mmc_Status & CmdSent))
- timeout--;
-
- if (timeout == 0) {
- error = MMC_CMD_RSP_TIMEOUT;
- return error;
- }
-
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags; //clear all the static flags
-
- return error;
-}
-
-t_mmc_error mmc_cmdresp145error(u8 cmd, u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 100000;
- status = t_mmc[card_num]->mmc_Status;
- while ((timeout > 0) && !(status & (CmdCrcFail | CmdRespEnd | CmdTimeOut)))
- {
- timeout--;
- status = t_mmc[card_num]->mmc_Status;
- }
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc[card_num]->mmc_Clear |= CmdTimeOut;
- return error;
- }
- else if (status & CmdCrcFail)
- {
- error = MMC_CMD_CRC_FAIL;
- t_mmc[card_num]->mmc_Clear |= CmdCrcFail;
- return error;
- }
-
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags; /*Clear Static flags */
- if (t_mmc[card_num]->mmc_RespCommand != cmd)
- {
- /* check response received for CMD7*/
- error = MMC_ILLEGAL_CMD;
- return error;
- }
- return error;
-}
-
-t_mmc_error mmc_cmdresp2error(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 100000;
- status = t_mmc[card_num]->mmc_Status;
- while ((timeout > 0) && !(status & (CmdCrcFail | CmdTimeOut | CmdRespEnd)))
- {
- timeout--;
- status = t_mmc[card_num]->mmc_Status;
- }
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc[card_num]->mmc_Clear |= CmdTimeOut;
- return error;
- }
- else if (status & CmdCrcFail)
- {
- error = MMC_CMD_CRC_FAIL;
- t_mmc[card_num]->mmc_Clear |= CmdCrcFail;
- return error;
- }
-
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags; /*Clear Static flags */
-
- return error;
-}
-
-t_mmc_error mmc_cmdresp3error(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 0x100000;
- status = t_mmc[card_num]->mmc_Status;
- while ((timeout > 0) && !(status & (CmdRespEnd | CmdTimeOut | CmdCrcFail)))
- {
- timeout--;
- status = t_mmc[card_num]->mmc_Status;
- }
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc[card_num]->mmc_Clear |= CmdTimeOut;
- return error;
- }
-
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags;
- return error;
-}
-
-t_mmc_error mmc_cmdresp6error(u8 cmd, u16 * p_rca, u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 status;
- u32 response_r1;
-
- status = t_mmc[card_num]->mmc_Status;
- while (!(status & (CmdRespEnd | CmdTimeOut | CmdCrcFail)))
- {
- status = t_mmc[card_num]->mmc_Status;
- }
-
- if (status & CmdTimeOut)
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc[card_num]->mmc_Clear |= CmdTimeOut;
- return (error);
- }
- else if (status & CmdCrcFail)
- {
- error = MMC_CMD_CRC_FAIL;
- t_mmc[card_num]->mmc_Clear |= CmdCrcFail;
- return (error);
- }
-
- /* CHECK RESPONSE RECEIVED IS OF DESIRED COMMAND */
- if (t_mmc[card_num]->mmc_RespCommand != cmd)
- {
- error = MMC_ILLEGAL_CMD;
- return (error);
- }
-
- /*Clear Static flags*/
- t_mmc[card_num]->mmc_Clear = ClrStaticFlags;
-
- /* WE HAVE RECEIVED RESPONSE, RETRIEVE IT. */
- response_r1 = t_mmc[card_num]->mmc_Response0;
-
- if (AllZero == (response_r1 & (R6_GEN_UNKNOWN_ERROR | R6_ILLEGAL_CMD | R6_COM_CRC_FAILED)))
- {
- *p_rca = (u16) (response_r1 >> 16);
- return (error);
- }
-
- if (response_r1 & R6_GEN_UNKNOWN_ERROR)
- {
- return (MMC_GENERAL_UNKNOWN_ERROR);
- }
-
- if (response_r1 & R6_ILLEGAL_CMD)
- {
- return (MMC_ILLEGAL_CMD);
- }
-
- if (response_r1 & R6_COM_CRC_FAILED)
- {
- return (MMC_COM_CRC_FAILED);
- }
-
- return (error);
-}
-
-t_mmc_error mmc_cmdresp7error(u8 card_num)
-{
- t_mmc_error error = MMC_OK;
- u32 status;
- u32 timeout = 10000;
-
- status = t_mmc[card_num]->mmc_Status;
- while (!(status & (CmdCrcFail | CmdRespEnd | CmdTimeOut)) && (timeout > 0))
- {
- timeout--;
- status = t_mmc[card_num]->mmc_Status;
- }
-
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- /* Card is not V2.0 complient or card does not support the set voltage range */
- error = MMC_CMD_RSP_TIMEOUT;
- return (error);
- }
-
- if (status & CmdRespEnd)
- {
- /* Card is V2.0 complient */
- error = MMC_OK;
- return (error);
- }
-
- return (error);
-}
-
-t_mmc_error mmc_iscardprogramming(u8 card_num, u8 * status)
-{
- t_mmc_error error;
- u32 response;
-
- t_mmc[card_num]->mmc_Argument = card_array[card_num].RCA;//0x1 << 16; //RCA
- t_mmc[card_num]->mmc_Command = SEND_STATUS | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(SEND_STATUS, card_num);
- if (error != MMC_OK)
- return error;
-
- response = t_mmc[card_num]->mmc_Response0;
- *status = (response >> 9) & 0x0000000f;
-
- return error;
-
-}
-
-t_mmc_error mmc_sendstatus(u8 cardno, u32 * status)
-{
- t_mmc_error error = MMC_OK;
-
- t_mmc0->mmc_Argument = card_array[cardno].RCA;//card_array[cardno - 1].RCA << 16; //RCA
- t_mmc0->mmc_Command = SEND_STATUS | RespExpected | CmdPathEnable;
-
- error = mmc_cmdresp145error(SEND_STATUS, cardno);
- if (error != MMC_OK)
- return error;
-
- *status = t_mmc0->mmc_Response0;
-
- return error;
-}
-
-t_mmc_error mmc_cmderror_2(void)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 0xefffffff;
- status = t_mmc0->mmc_Status;
- while ((timeout > 0) && !(status & (CmdSent| CmdCrcFail | CmdTimeOut | CmdRespEnd)))
- {
- timeout--;
- status = t_mmc0->mmc_Status;
- }
-
- if (timeout == 0)
- {
- printf(" cmd1 timeout error\n");
- error = MMC_CMD_RSP_TIMEOUT;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static flags
-
- return error;
-}
-
-t_mmc_error mmc_cmdresp2error_2(void)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 0xefffffff; //(u32)((float)(64/(float)clockfreq )/ ((float)(1/(float)MCLK) + 8*(float)(1/(float)PROCESSOR_CLK)));
- status = t_mmc0->mmc_Status;
-
- while ((timeout > 0) && !(status & (CmdCrcFail | CmdTimeOut | CmdRespEnd)))
- {
- timeout--;
- status = t_mmc0->mmc_Status;
- }
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc0->mmc_Clear |= CmdTimeOut;
- return error;
- }
- if (status & CmdCrcFail)
- {
- error = MMC_CMD_CRC_FAIL;
- t_mmc0->mmc_Clear |= CmdCrcFail;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; /*Clear Static flags */
-
- return error;
-}
-
-t_mmc_error mmc_cmdresp3error_2(void)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 0xefffffff;
- status = t_mmc0->mmc_Status;
-
- while ((timeout > 0) && !(status & (CmdRespEnd | CmdTimeOut | CmdCrcFail)))
- {
- timeout--;
- status = t_mmc0->mmc_Status;
- }
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc0->mmc_Clear |= CmdTimeOut;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags;
-
- return error;
-}
-
-t_mmc_error mmc_cmdresp145error_2(u8 cmd)
-{
- t_mmc_error error = MMC_OK;
- u32 status, timeout;
-
- timeout = 0xefffffff;
- status = t_mmc0->mmc_Status;
-
- while ((timeout > 0) && !(status & (CmdCrcFail | CmdRespEnd | CmdTimeOut)))
- {
- timeout--;
- status = t_mmc0->mmc_Status;
- }
- if ((timeout == 0) || (status & CmdTimeOut))
- {
- error = MMC_CMD_RSP_TIMEOUT;
- t_mmc0->mmc_Clear |= CmdTimeOut;
- return error;
- }
- else if (status & CmdCrcFail)
- {
- error = MMC_CMD_CRC_FAIL;
- t_mmc0->mmc_Clear |= CmdCrcFail;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; /*Clear Static flags */
- if (t_mmc0->mmc_RespCommand != cmd)
- {
- /* check response received for CMD7*/
- error = MMC_ILLEGAL_CMD;
- return error;
- }
-
- return error;
-}
-
-t_mmc_error mmc_cmdreadresp(u32 * tempbuff)
-{
- t_mmc_error error = MMC_OK;
- u32 i;
- u32 timeout = 0;
-
- timeout = 0xefffffff;
-
- while ((timeout > 0) && !(t_mmc0-> mmc_Status & (RxOverrun | DataCrcFail | DataTimeOut |DataBlockEnd)))
- {
- timeout--;
- if (t_mmc0->mmc_Status & RxFifoHalfFull)
- {
- for (i = 0; i < 8; i++)
- {
- *(tempbuff + i) = t_mmc0->mmc_Fifo;
- }
- tempbuff += 8;
- }
- }
- if ((timeout == 0) || (t_mmc0->mmc_Status & DataTimeOut))
- {
- t_mmc0->mmc_Clear |= DataTimeOut;
- return error;
- }
- else if (t_mmc0->mmc_Status & DataCrcFail)
- {
- t_mmc0->mmc_Clear |= DataCrcFail;
- error = MMC_DATA_CRC_FAIL;
- return error;
- }
- else if (t_mmc0->mmc_Status & RxOverrun)
- {
- t_mmc0->mmc_Clear |= RxOverrun;
- error = MMC_RX_OVERRUN;
- return error;
- }
-
- while (t_mmc0->mmc_Status & RxDataAvlbl)
- {
- *tempbuff = t_mmc0->mmc_Fifo;
- tempbuff++;
- }
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags
-
- return error;
-}
-
-t_mmc_error mmc_waitcmdreadresp(void)
-{
- t_mmc_error error = MMC_OK;
- u32 timeout = 0;
-
- timeout = 0xefffffff;
-
- while (!(t_mmc0->mmc_Status & (RxOverrun | DataCrcFail | DataTimeOut | DataBlockEnd)))
- {
-
- }
-
- if ((timeout == 0) || (t_mmc0->mmc_Status & DataTimeOut))
- {
- t_mmc0->mmc_Clear |= DataTimeOut;
- return error;
- }
- else if (t_mmc0->mmc_Status & DataCrcFail)
- {
- t_mmc0->mmc_Clear |= DataCrcFail;
- error = MMC_DATA_CRC_FAIL;
- return error;
- }
- else if (t_mmc0->mmc_Status & RxOverrun)
- {
- t_mmc0->mmc_Clear |= RxOverrun;
- error = MMC_RX_OVERRUN;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags
-
- return error;
-}
-
-t_mmc_error mmc_iscardprogramming_2(u8 * status)
-{
- t_mmc_error error;
- u32 response;
- t_mmc_command_control commcontrol;
-
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = FALSE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_sendcommand(MMC_SEND_STATUS, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp145error_2(MMC_SEND_STATUS);
-
- if (error != MMC_OK)
- return error;
-
- response = t_mmc0->mmc_Response0;
- *status = (response >> 9) & 0x0000000f;
-
- return error;
-}
-
-t_mmc_error mmc_cmdwriteresp(u8 cardno, u32 * tempbuff, u16 total_num_of_bytes)
-{
- u32 timeout = 0;
- t_mmc_error error = MMC_OK;
- u32 bytes_transferred = 0;
- u32 i, j;
- u8 cardstate;
-
- timeout = 0xefffffff;
-
- while ((timeout > 0) && !(t_mmc0-> mmc_Status & (DataBlockEnd | TxUnderrun | DataCrcFail | DataTimeOut)))
- {
- timeout--;
- if (t_mmc0->mmc_Status & TxFifoHalfEmpty)
- {
- if ((total_num_of_bytes - bytes_transferred) < 32)
- {
- j = ((total_num_of_bytes - bytes_transferred) % 4 ==0) ?
- ((total_num_of_bytes - bytes_transferred) / 4) :
- ((total_num_of_bytes - bytes_transferred) / 4 + 1);
-
- for (i = 0; i < j; i++, tempbuff++, bytes_transferred += 4)
- t_mmc0->mmc_Fifo = *tempbuff;
- }
- else
- {
- for (i = 0; i < 8; i++)
- t_mmc0->mmc_Fifo = *(tempbuff + i);
- tempbuff += 8;
- bytes_transferred += 32;
- }
- }
- }
-
- if ((timeout == 0) || (t_mmc0->mmc_Status & DataTimeOut))
- {
- t_mmc0->mmc_Clear |= DataTimeOut;
- error = MMC_DATA_TIMEOUT;
- printf(" mmc_cmdwriteresp timeout error \n");
- return error;
- }
- else if (t_mmc0->mmc_Status & DataCrcFail)
- {
- t_mmc0->mmc_Clear |= DataCrcFail;
- error = MMC_DATA_CRC_FAIL;
- printf(" mmc_cmdwriteresp CRC error \n");
- return error;
- }
- else if (t_mmc0->mmc_Status & TxUnderrun)
- {
- t_mmc0->mmc_Clear |= TxUnderrun;
- error = MMC_TX_UNDERRUN;
- printf(" mmc_cmdwriteresp underrun error \n");
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags
-
- error = mmc_iscardprogramming_2(&cardstate);
- while (error == MMC_OK && cardstate == 7)
- error = mmc_iscardprogramming_2(&cardstate);
-
- return error;
-}
-
-t_mmc_error mmc_waitcmdwriteresp(u8 cardno, u32 * tempbuff, u16 total_num_of_bytes)
-{
- u32 timeout = 0;
- t_mmc_error error = MMC_OK;
- u8 cardstate;
-
- timeout = 0xefffffff;
-
- while ((timeout > 0) && !(t_mmc0-> mmc_Status & (DataBlockEnd | TxUnderrun | DataCrcFail | DataTimeOut)))
- {
-
- }
-
- if ((timeout == 0) || (t_mmc0->mmc_Status & DataTimeOut))
- {
- t_mmc0->mmc_Clear |= DataTimeOut;
- error = MMC_DATA_TIMEOUT;
- return error;
-
- }
- else if (t_mmc0->mmc_Status & DataCrcFail)
- {
- t_mmc0->mmc_Clear |= DataCrcFail;
- error = MMC_DATA_CRC_FAIL;
- return error;
- }
- else if (t_mmc0->mmc_Status & TxUnderrun)
- {
- t_mmc0->mmc_Clear |= TxUnderrun;
- error = MMC_TX_UNDERRUN;
- return error;
- }
-
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags
-
- error = mmc_iscardprogramming_2(&cardstate);
- while (error == MMC_OK && cardstate == 7)
- error = mmc_iscardprogramming_2(&cardstate);
-
- return error;
-}
diff --git a/board/st/u8500/mmc.h b/board/st/u8500/mmc.h
deleted file mode 100644
index 069aced00..000000000
--- a/board/st/u8500/mmc.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-#ifndef _MMC_H_
-#define _MMC_H_
-
-#include <common.h>
-#include "asm-arm/arch-stw8500/mmc.h"
-
-/*---------------------------------------------------------------------------
- * Enums
- *---------------------------------------------------------------------------*/
-
-extern char *mmc_error_name[];
-
-#define t_mmc_irq_src u32
-
-typedef enum {
- MMC_CMD_CRC_FAIL_INT = 0x00000001,
- MMC_DATA_CRC_FAIL_INT = 0x00000002,
- MMC_CMD_TIMEOUT_INT = 0x00000004,
- MMC_DATA_TIMEOUT_INT = 0x00000008,
- MMC_TX_UNDERRUN_INT = 0x00000010,
- MMC_RX_OVERRUN_INT = 0x00000020,
- MMC_CMD_RESP_OK_INT = 0x00000040,
- MMC_CMD_SENT_INT = 0x00000080,
- MMC_DATA_END_INT = 0x00000100,
- MMC_DATA_BLOCK_OK_INT = 0x00000400,
- MMC_CMD_ACTIVE_INT = 0x00000800,
- MMC_TX_ACTIVE_INT = 0x00001000,
- MMC_RX_ACTIVE_INT = 0x00002000,
- MMC_TX_FIFO_HALF_EMPTY_INT = 0x00004000,
- MMC_RX_FIFO_HALF_FULL_INT = 0x00008000,
- MMC_TX_FIFO_FULL_INT = 0x00010000,
- MMC_RX_FIFO_FULL_INT = 0x00020000,
- MMC_TX_FIFO_EMPTY_INT = 0x00040000,
- MMC_RX_FIFO_EMPTY_INT = 0x00080000,
- MMC_TX_DATA_AVLBL_INT = 0x00100000,
- MMC_RX_DATA_AVLBL_INT = 0x00200000,
- MMC_ALL_STATIC_IT = 0x000005FF,
- MMC_ALL_IT = 0x003FFDFF
-
-} t_mmc_interrupt;
-
-typedef enum {
- MMC_DISABLE = 0,
- MMC_ENABLE
-} t_mmc_state;
-
-
-typedef enum {
- MMC_POWER_OFF = 0x0,
- MMC_POWER_UP = 0x2,
- MMC_POWER_ON = 0x3
-} t_mmc_power_state;
-
-typedef enum {
- MMC_PUSH_PULL = 0,
- MMC_OPEN_DRAIN
-} t_mmc_bus_mode;
-
-typedef enum {
- MMC_GO_IDLE_STATE = 0,
- MMC_SEND_OP_COND = 1,
- MMC_ALL_SEND_CID = 2,
- MMC_SET_REL_ADDR = 3,
- MMC_SET_DSR = 4,
- MMC_SEL_DESEL_CARD = 7,
- MMC_SEND_CSD = 9,
- MMC_SEND_CID = 10,
- MMC_READ_DAT_UNTIL_STOP = 11,
- MMC_STOP_TRANSMISSION = 12,
- MMC_SEND_STATUS = 13,
- MMC_GO_INACTIVE_STATE = 15,
- MMC_SET_BLOCKLEN = 16,
- MMC_READ_SINGLE_BLOCK = 17,
- MMC_READ_MULT_BLOCK = 18,
- MMC_WRITE_DAT_UNTIL_STOP = 20,
- MMC_SET_BLOCK_COUNT = 23,
- MMC_WRITE_SINGLE_BLOCK = 24,
- MMC_WRITE_MULT_BLOCK = 25,
- MMC_PROG_CID = 26,
- MMC_PROG_CSD = 27,
- MMC_SET_WRITE_PROT = 28,
- MMC_CLR_WRITE_PROT = 29,
- MMC_SEND_WRITE_PROT = 30,
- MMC_ERASE_GRP_START = 35,
- MMC_ERASE_GRP_END = 36,
- MMC_ERASE = 38,
- MMC_FAST_IO = 39,
- MMC_GO_IRQ_STATE = 40,
- SD_SEND_OP_COND = 41,
- MMC_LOCK_UNLOCK = 42,
- MMC_APP_CMD = 55,
- MMC_GEN_CMD = 56,
- MMC_NO_CMD = 64
-} t_mmc_command_index;
-
-typedef enum {
- MMC_SHORT_RESP = 0,
- MMC_LONG_RESP
-} t_mmc_response_type;
-
-
-typedef enum {
- MMC_WRITE= 0,
- MMC_READ
-} t_mmc_transfer_direction;
-
-typedef enum {
- MMC_BLOCK = 0,
- MMC_STREAM
-} t_mmc_transfer_type;
-
-typedef enum {
- POLLING_MODE = 0,
- INTERRUPT_MODE,
- DMA_MODE
-} t_mmc_device_mode;
-
-/*---------------------------------------------------------------------------
- * Structures
- *---------------------------------------------------------------------------*/
-
-typedef struct {
- t_mmc_bus_mode mode;
- t_mmc_state rodctrl;
-} t_mmc_bus_configuration;
-
-typedef struct {
- t_mmc_state pwrsave;
- t_mmc_state bypass;
- t_mmc_state widebus;
-} t_mmc_clock_control;
-
-typedef struct {
- t_bool IsRespExpected;
- t_bool IsLongResp;
- t_bool IsInterruptMode;
- t_bool IsPending;
- t_mmc_state cmdpath;
-} t_mmc_command_control;
-
-
-#define t_mmc_event u32
-
-#define t_mmc_filter_mode u32
-#define NO_FILTER_MODE 0
-
-typedef enum
-{
- MMC_NEW = 0,
- MMC_OLD
-} t_mmc_irq_status_usage;
-
-typedef struct
-{
- t_mmc_irq_status_usage usage;
- u32 IRQStatus;
- u32 EventStatus;
-} t_mmc_irq_status;
-
-typedef enum {
-
- MMC_MULTIMEDIA_CARD,
- MMC_SECURE_DIGITAL_CARD,
- MMC_SECURE_DIGITAL_IO_CARD,
- MMC_HIGH_SPEED_MULTIMEDIA_CARD,
- MMC_SECURE_DIGITAL_IO_COMBO_CARD
-
-} t_mmc_card_type;
-
-typedef struct {
- u32 CID[4];
- u32 CSD[4];
- u16 RCA;
- t_mmc_card_type card_type;
- u8 padding;
- u8 sdio_cccr[4]; /* I/O ready, CCCR/SDIO revision, SD Specification revision, and Card Capability registers */
- int blockaddressed;
-} t_mmc_card_info;
-
-typedef struct {
- t_mmc_error error;
- u16 transferred_bytes;
-} t_mmc_last_transfer_info;
-
-typedef enum {
- NO_TRANSFER = 0,
- TRANSFER_IN_PROGRESS
-} t_mmc_transfer_state;
-
-typedef enum {
- WRITE_PROT_WHOLE_CARD_TEMP = 0,
- WRITE_PROT_WHOLE_CARD_PERM,
- WRITE_PROT_SINGLE_GROUP
-} t_mmc_write_protect_type;
-
-/*---------------------------------------------------------------------------
- * Functions Prototype
- *---------------------------------------------------------------------------*/
-
-
-t_mmc_error mmc_init (u8,t_logical_address) ;
-
-t_mmc_error mmc_setpowerstate(t_mmc_power_state);
-t_mmc_power_state mmc_getpowerstate(void);
-t_mmc_error mmc_setoperatingvoltage(u8);
-u8 mmc_getoperatingvoltage (void);
-t_mmc_error mmc_configbus(t_mmc_bus_configuration);
-
-t_mmc_error mmc_setclock(t_mmc_state);
-t_mmc_error mmc_configclockcontrol(t_mmc_clock_control);
-t_mmc_error mmc_setclockfrequency(u8);
-t_mmc_error mmc_sendcommand(t_mmc_command_index, u32,t_mmc_command_control) ;
-t_mmc_command_index mmc_getcommandresponse(void) ;
-t_mmc_error mmc_getresponse(t_mmc_response_type, u32*) ;
-t_mmc_error mmc_setdatapath(t_mmc_state);
-t_mmc_error mmc_setdatatimeout(u32);
-t_mmc_error mmc_setdatalength(u16);
-t_mmc_error mmc_setdatablocklength(u8);
-t_mmc_error mmc_settransferdirection(t_mmc_transfer_direction) ;
-t_mmc_error mmc_settransfertype(t_mmc_transfer_type);
-t_mmc_error mmc_handledma(t_mmc_state);
-u16 mmc_getdatacounter(void);
-
-t_mmc_error mmc_selectsdcard(u8);
-t_mmc_error mmc_poweron(u8) ;
-t_mmc_error mmc_poweroff(u8);
-t_mmc_error mmc_initializeCards(u8);
-t_mmc_error mmc_getcardinfo(u8, t_mmc_card_info *) ;
-t_mmc_error mmc_setdevicemode(t_mmc_device_mode);
-t_mmc_error mmc_readbytes(u8, u32, u32*, u16) ;
-t_mmc_error mmc_readblocks(u8, u32, u32*, u16, u16) ;
-t_mmc_error mmc_writebytes(u8, u32, u32* , u16) ;
-t_mmc_error mmc_writeblocks(u8, u32, u32*, u16, u16) ;
-t_mmc_transfer_state mmc_gettransferstate(void);
-t_mmc_error mmc_erase(u8, u32, u32) ;
-
-u8 convert_from_bytes_to_power_of_two (u16 no_of_bytes);
-
-/*New Interrupt strategy(M1 functions)*/
-void mmc_acknowledgementevent(t_mmc_event *);
-
-#endif /* _MMC_H_ */
diff --git a/board/st/u8500/mmc_host.c b/board/st/u8500/mmc_host.c
new file mode 100644
index 000000000..479e76391
--- /dev/null
+++ b/board/st/u8500/mmc_host.c
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com>
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+/*#define DEBUG*/
+
+#include "common.h"
+#include <mmc.h>
+#include "gpio.h" /* two copies of gpio.h exists - why? */
+#include "mmc_host.h"
+#include <malloc.h>
+
+struct mmc_host {
+ struct sdi_registers *base;
+};
+
+/*
+ * wait_for_command_end() - waiting for the command completion
+ * this function will wait till the command completion has happened or
+ * any error generated by reading the status register
+ */
+static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
+{
+ u32 hoststatus, statusmask;
+ struct mmc_host *host = dev->priv;
+
+ statusmask = SDI_STA_CTIMEOUT | SDI_STA_CCRCFAIL;
+ if ((cmd->resp_type & MMC_RSP_PRESENT))
+ statusmask |= SDI_STA_CMDREND;
+ else
+ statusmask |= SDI_STA_CMDSENT;
+
+ do
+ hoststatus = readl(&host->base->status) & statusmask;
+ while (!hoststatus);
+
+ debug("SDI_ICR <= 0x%08X\n", statusmask);
+ writel(statusmask, &host->base->status_clear);
+
+ if (hoststatus & SDI_STA_CTIMEOUT) {
+ debug("CMD%d time out\n", cmd->cmdidx);
+ return TIMEOUT;
+ } else if ((hoststatus & SDI_STA_CCRCFAIL) &&
+ (cmd->flags & MMC_RSP_CRC)) {
+ debug("CMD%d CRC error\n", cmd->cmdidx);
+ return MMC_CMD_CRC_FAIL;
+ }
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ cmd->response[0] = readl(&host->base->response0);
+ cmd->response[1] = readl(&host->base->response1);
+ cmd->response[2] = readl(&host->base->response2);
+ cmd->response[3] = readl(&host->base->response3);
+ debug("CMD%d response[0]:0x%08X, response[1]:0x%08X, "
+ "response[2]:0x%08X, response[3]:0x%08X\n",
+ cmd->cmdidx, cmd->response[0], cmd->response[1],
+ cmd->response[2], cmd->response[3]);
+ }
+ return MMC_OK;
+}
+
+/*
+ * do_command - sends command to card, and waits for its result.
+ */
+static int do_command(struct mmc *dev, struct mmc_cmd *cmd)
+{
+ int result;
+ u32 sdi_cmd = 0;
+ struct mmc_host *host = dev->priv;
+
+ debug("Request to do CMD%d on %s\n", cmd->cmdidx, dev->name);
+
+ sdi_cmd = (cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN;
+
+ if (cmd->resp_type) {
+ sdi_cmd |= SDI_CMD_WAITRESP;
+ if (cmd->resp_type & MMC_RSP_136)
+ sdi_cmd |= SDI_CMD_LONGRESP;
+ }
+
+ debug("SDI_ARG <= 0x%08X\n", cmd->cmdarg);
+ writel((u32)cmd->cmdarg, &host->base->argument);
+ udelay(COMMAND_REG_DELAY); /* DONT REMOVE */
+ debug("SDI_CMD <= 0x%08X\n", sdi_cmd);
+ writel(sdi_cmd, &host->base->command);
+
+ result = wait_for_command_end(dev, cmd);
+
+ /* After CMD2 set RCA to a none zero value. */
+ if ((result == MMC_OK) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID))
+ dev->rca = 10;
+
+ /* After CMD3 open drain is switched off and push pull is used. */
+ if ((result == MMC_OK) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) {
+ u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD;
+ debug("SDI_PWR <= 0x%08X\n", sdi_pwr);
+ writel(sdi_pwr, &host->base->power);
+ }
+
+ return result;
+}
+
+static int convert_from_bytes_to_power_of_two(unsigned int x)
+{
+ int y = 0;
+ y = (x & 0xAAAA) ? 1 : 0;
+ y |= ((x & 0xCCCC) ? 1 : 0)<<1;
+ y |= ((x & 0xF0F0) ? 1 : 0)<<2;
+ y |= ((x & 0xFF00) ? 1 : 0)<<3;
+
+ return y;
+}
+
+/*
+ * read_bytes - reads bytes from the card, part of data transfer.
+ */
+static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize)
+{
+ u32 *tempbuff = dest;
+ int i;
+ u64 xfercount = blkcount * blksize;
+ struct mmc_host *host = dev->priv;
+ u32 status;
+ u32 status_err;
+
+ debug("read_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
+
+ status = readl(&host->base->status);
+ status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+ while (!status_err &&
+ (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32))) {
+ if (status & SDI_STA_RXFIFOBR) {
+ for (i = 0; i < SDI_FIFO_BURST_SIZE; i++)
+ *(tempbuff + i) = readl(&host->base->fifo);
+ tempbuff += SDI_FIFO_BURST_SIZE;
+ xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32);
+ }
+ status = readl(&host->base->status);
+ status_err = status &
+ (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+ }
+
+ if (status & SDI_STA_DTIMEOUT) {
+ printf("Reading data timedout, xfercount:%llu,"
+ "status:0x%08X\n", xfercount, status);
+ return MMC_DATA_TIMEOUT;
+ } else if (status & SDI_STA_DCRCFAIL) {
+ printf("Reading data CRC error\n");
+ return MMC_DATA_CRC_FAIL;
+ }
+
+ while ((!status_err) && (xfercount >= sizeof(u32))) {
+ if (status & SDI_STA_RXDAVL) {
+ *(tempbuff) = readl(&host->base->fifo);
+ tempbuff++;
+ xfercount -= sizeof(u32);
+ }
+ status = readl(&host->base->status);
+ status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+ }
+
+ /* Wait for DBCKEND */
+ status_err = status &
+ (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
+ while (!status_err) {
+ status = readl(&host->base->status);
+ status_err = status &
+ (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
+ }
+
+ if (status & SDI_STA_DTIMEOUT) {
+ printf("Reading data timedout, xfercount:%llu,"
+ "status:0x%08X\n", xfercount, status);
+ return MMC_DATA_TIMEOUT;
+ } else if (status & SDI_STA_DCRCFAIL) {
+ printf("Reading data CRC error\n");
+ return MMC_DATA_CRC_FAIL;
+ }
+
+ debug("SDI_ICR <= 0x%08X\n", SDI_ICR_MASK);
+ writel(SDI_ICR_MASK, &host->base->status_clear);
+ debug("Reading loop ended\n");
+
+ if (xfercount) {
+ printf("Reading data error, xfercount:%llu",
+ (unsigned long long) xfercount);
+ return MMC_GENERAL_UNKNOWN_ERROR;
+ }
+
+ return MMC_OK;
+}
+
+/*
+ * write_bytes - writes byte to the card, part of data transfer.
+ */
+static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize)
+{
+ u32 *tempbuff = src;
+ int i;
+ u64 xfercount = blkcount * blksize;
+ struct mmc_host *host = dev->priv;
+ u32 status;
+ u32 status_err;
+
+ debug("write_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
+
+ status = readl(&host->base->status);
+ status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+ while (!status_err && xfercount) {
+ if (status & SDI_STA_TXFIFOBW) {
+ if (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32)) {
+ for (i = 0; i < SDI_FIFO_BURST_SIZE; i++)
+ writel(*(tempbuff + i),
+ &host->base->fifo);
+ tempbuff += SDI_FIFO_BURST_SIZE;
+ xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32);
+ } else {
+ while (xfercount >= sizeof(u32)) {
+ writel(*(tempbuff), &host->base->fifo);
+ tempbuff++;
+ xfercount -= sizeof(u32);
+ }
+ }
+ }
+ status = readl(&host->base->status);
+ status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+ }
+
+ /* Wait for DBCKEND */
+ status_err = status &
+ (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
+ while (!status_err) {
+ status = readl(&host->base->status);
+ status_err = status &
+ (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
+ }
+
+ if (status & SDI_STA_DTIMEOUT) {
+ printf(
+ "Writing data timedout, xfercount:%llu,status:0x%08X\n",
+ xfercount, status);
+ return MMC_DATA_TIMEOUT;
+ } else if (status & SDI_STA_DCRCFAIL) {
+ printf("Writing data CRC error\n");
+ return MMC_DATA_CRC_FAIL;
+ }
+
+
+ writel(SDI_ICR_MASK, &host->base->status_clear);
+ debug("Writing data loop completed status:0x%08X\n", status);
+
+ if (xfercount) {
+ printf("Writing data error, xfercount:%llu",
+ (unsigned long long) xfercount);
+ return MMC_GENERAL_UNKNOWN_ERROR;
+ }
+
+ return MMC_OK;
+}
+
+/*
+ * do_data_transfer - for doing any data transfer operation.
+ *
+ * dev: mmc device for doing the operation on.
+ * cmd: cmd to do.
+ * data: if cmd warrants any data transfer.
+ */
+static int do_data_transfer(struct mmc *dev,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ int error = MMC_DATA_TIMEOUT;
+ struct mmc_host *host = dev->priv;
+ u32 blksz = 0;
+ u32 data_ctrl = 0;
+ u32 data_len = (u32) (data->blocks * data->blocksize);
+
+ debug("Request to do data xfer on %s\n", dev->name);
+ debug("do_data_transfer(%u) start\n", data->blocks);
+
+ blksz = convert_from_bytes_to_power_of_two(data->blocksize);
+ data_ctrl |= (blksz << INDEX(SDI_DCTRL_DBLOCKSIZE_MASK));
+ data_ctrl |= SDI_DCTRL_DTEN;
+
+ debug("SDI_DTIMER <= 0x%08X\n", SDI_DTIMER_DEFAULT);
+ writel(SDI_DTIMER_DEFAULT, &host->base->datatimer);
+ debug("SDI_DLEN <= 0x%08X\n", data_len);
+ writel(data_len, &host->base->datalength);
+ udelay(DATA_REG_DELAY); /* DONT REMOVE */
+
+ if (data->flags & (MMC_DATA_READ)) {
+ debug("It is a read operation\n");
+
+ data_ctrl |= SDI_DCTRL_DTDIR_IN;
+ debug("SDI_DCTRL <= 0x%08X\n", data_ctrl);
+ writel(data_ctrl, &host->base->datactrl);
+
+ error = do_command(dev, cmd);
+ if (error)
+ return error;
+
+ error = read_bytes(dev,
+ (u32 *)data->dest,
+ (u32)data->blocks,
+ (u32)data->blocksize);
+ } else if (data->flags & (MMC_DATA_WRITE)) {
+ debug("It is a write operation\n");
+
+ error = do_command(dev, cmd);
+ if (error)
+ return error;
+
+ debug("SDI_DCTRL <= 0x%08X\n", data_ctrl);
+ writel(data_ctrl, &host->base->datactrl);
+
+ error = write_bytes(dev,
+ (u32 *)data->src,
+ (u32)data->blocks,
+ (u32)data->blocksize);
+ }
+
+ debug("do_data_transfer() end\n");
+
+ return error;
+}
+
+/*
+ * host_request - For all operations on cards.
+ *
+ * dev: mmc device for doing the operation on.
+ * cmd: cmd to do.
+ * data: if cmd warrants any data transfer.
+ */
+static int host_request(struct mmc *dev,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ int result;
+
+ if (data)
+ result = do_data_transfer(dev, cmd, data);
+ else
+ result = do_command(dev, cmd);
+
+ return result;
+}
+
+/*
+ * This is to initialize card specific things just before enumerating
+ * them. MMC cards uses open drain drivers in enumeration phase.
+ */
+static int mmc_host_reset(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
+
+ debug("SDI_PWR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->power);
+ return MMC_OK;
+}
+
+/*
+ * This is to initialize card specific things just before enumerating
+ * them. SD cards does not need to be initialized.
+ */
+static int sd_host_reset(struct mmc *dev)
+{
+ return MMC_OK;
+}
+/*
+ * host_set_ios:to configure host parameters.
+ *
+ * dev: the pointer to the host structure for MMC.
+ */
+static void host_set_ios(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_clkcr;
+
+ /* First read out the contents of clock control register. */
+ sdi_clkcr = readl(&host->base->clock);
+
+ /* Set the clock rate and bus width */
+ if (dev->clock) {
+ u32 clkdiv = 0;
+ u32 tmp_clock;
+
+ debug("setting clock and bus width in the host:");
+ if (dev->clock >= dev->f_max) {
+ clkdiv = 0;
+ dev->clock = dev->f_max;
+ } else {
+ clkdiv = (MCLK / dev->clock) - 2;
+ }
+ tmp_clock = MCLK / (clkdiv + 2);
+ while (tmp_clock > dev->clock) {
+ clkdiv++;
+ tmp_clock = MCLK / (clkdiv + 2);
+ }
+ if (clkdiv > SDI_CLKCR_CLKDIV_MASK)
+ clkdiv = SDI_CLKCR_CLKDIV_MASK;
+ tmp_clock = MCLK / (clkdiv + 2);
+ dev->clock = tmp_clock;
+ sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK);
+ sdi_clkcr |= clkdiv;
+ }
+
+ if (dev->bus_width) {
+ u32 buswidth = 0;
+
+ switch (dev->bus_width) {
+ case 1:
+ buswidth |= SDI_CLKCR_WIDBUS_1;
+ break;
+ case 4:
+ buswidth |= SDI_CLKCR_WIDBUS_4;
+ break;
+ case 8:
+ buswidth |= SDI_CLKCR_WIDBUS_8;
+ break;
+ default:
+ printf("wrong bus width, so ignoring");
+ break;
+ }
+ sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK);
+ sdi_clkcr |= buswidth;
+ }
+
+ debug("SDI_CLKCR <= 0x%08X\n", sdi_clkcr);
+ writel(sdi_clkcr, &host->base->clock);
+ udelay(CLK_CHANGE_DELAY);
+}
+
+struct mmc *alloc_mmc_struct(void)
+{
+ struct mmc_host *host = NULL;
+ struct mmc *mmc_device = NULL;
+
+ host = malloc(sizeof(struct mmc_host));
+ if (!host)
+ return NULL;
+
+ mmc_device = malloc(sizeof(struct mmc));
+ if (!mmc_device)
+ goto err;
+
+ mmc_device->priv = host;
+ return mmc_device;
+ err:
+ free(host);
+ return NULL;
+}
+
+static int host_poweroff(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ u32 sdi_pwr = ~SDI_PWR_PWRCTRL_ON;
+ debug("SDI_PWR <= 0x%08X\n", sdi_pwr);
+ writel(sdi_pwr, &host->base->power);
+ return 0;
+}
+
+/*
+ * emmc_host_init - initialize the emmc controller.
+ * Configure GPIO settings, set initial clock and power for emmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int emmc_host_init(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ gpio_error gpioerror;
+ u32 sdi_u32;
+
+ /* TODO: Investigate what is actually needed of the below. */
+
+ if (u8500_is_earlydrop()) {
+ debug("configuring EMMC for ED\n");
+ /* Initialize the gpio alternate function for eMMC */
+ struct gpio_register *p_gpio_register =
+ (void *)IO_ADDRESS(CFG_GPIO_6_BASE);
+ p_gpio_register->gpio_dats |= 0x0000FFE0;
+ p_gpio_register->gpio_pdis &= ~0x0000FFE0;
+
+ gpioerror = gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
+ if (GPIO_OK != gpioerror) {
+ printf(
+ "emmc_host_init() gpio_altfuncenable %d failed\n",
+ gpioerror);
+ goto end;
+ }
+
+ host->base = (struct sdi_registers *)CFG_EMMC_BASE_ED;
+ } else {
+ debug("configuring EMMC for V1\n");
+ /* enable the alternate function of PoP EMMC */
+ gpioerror = gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
+ if (gpioerror != GPIO_OK) {
+ printf(
+ "emmc_host_init() gpio_altfuncenable %d failed \n",
+ gpioerror);
+ goto end;
+ }
+ host->base = (struct sdi_registers *)CFG_EMMC_BASE_V1;
+ }
+
+ sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
+ debug("SDI_PWR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->power);
+ /* setting clk freq less than 400KHz */
+ sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
+ debug("SDI_CLKCR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->clock);
+ udelay(CLK_CHANGE_DELAY);
+ sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
+ debug("SDI_MASK0 <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->mask0);
+ dev->clock = MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
+ sprintf(dev->name, "EMMC");
+ dev->send_cmd = host_request;
+ dev->set_ios = host_set_ios;
+ dev->init = mmc_host_reset;
+ dev->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
+ MMC_MODE_HS_52MHz;
+ dev->voltages = VOLTAGE_WINDOW_MMC;
+ dev->f_min = dev->clock;
+ dev->f_max = MCLK / 2;
+ return 0;
+
+ end:
+ if (u8500_is_earlydrop())
+ gpio_altfuncdisable(GPIO_ALT_EMMC, "EMMC");
+ else
+ gpio_altfuncdisable(GPIO_ALT_POP_EMMC, "EMMC");
+
+ host_poweroff(dev);
+ return MMC_UNSUPPORTED_HW;
+}
+
+/*
+ * mmc_host_init - initialize the external mmc controller.
+ * Configure GPIO settings, set initial clock and power for mmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int mmc_host_init(struct mmc *dev)
+{
+ struct mmc_host *host = dev->priv;
+ gpio_error gpioerror;
+ struct gpio_register *gpio_base_address;
+ u32 sdi_u32;
+
+ gpio_base_address = (void *) IO_ADDRESS(CFG_GPIO_0_BASE);
+ gpio_base_address->gpio_dats |= 0xFFC0000;
+ gpio_base_address->gpio_pdis &= ~0xFFC0000;
+
+ /* save the GPIO0 AFSELA register */
+ gpioerror = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
+ if (gpioerror != GPIO_OK) {
+ printf("mmc_host_init() gpio_altfuncenable %d failed \n",
+ gpioerror);
+ goto end;
+ }
+
+ host->base = (struct sdi_registers *)CFG_MMC_BASE;
+ sdi_u32 = 0xBF;
+ debug("SDI_PWR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->power);
+ /* setting clk freq just less than 400KHz */
+ sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
+ debug("SDI_CLKCR <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->clock);
+ udelay(CLK_CHANGE_DELAY);
+ sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
+ debug("SDI_MASK0 <= 0x%08X\n", sdi_u32);
+ writel(sdi_u32, &host->base->mask0);
+ dev->clock = MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
+ sprintf(dev->name, "MMC");
+ dev->send_cmd = host_request;
+ dev->set_ios = host_set_ios;
+ dev->init = sd_host_reset;
+ dev->host_caps = /*MMC_MODE_4BIT*/ 0; /* Some SD cards do not work in
+ 4 bit mode! */
+ dev->voltages = VOLTAGE_WINDOW_SD;
+ dev->f_min = dev->clock;
+ dev->f_max = MCLK / 2;
+ return 0;
+
+ end:
+ gpio_altfuncdisable(GPIO_ALT_SD_CARD0, "MMC");
+ host_poweroff(dev);
+ return MMC_UNSUPPORTED_HW;
+}
+
+/*
+ * board_mmc_init - initialize all the mmc/sd host controllers.
+ * Called by generic mmc framework.
+ */
+int board_mmc_init(bd_t *bis)
+{
+ int error;
+ struct mmc *dev;
+
+ debug("mmc_host - board_mmc_init\n");
+
+ dev = alloc_mmc_struct();
+ if (!dev)
+ return -1;
+
+ error = emmc_host_init(dev);
+ if (error) {
+ printf("emmc_host_init() %d \n", error);
+ return -1;
+ }
+ mmc_register(dev);
+ debug("registered emmc interface number is:%d\n",
+ dev->block_dev.dev);
+
+ dev = alloc_mmc_struct();
+ if (!dev)
+ return -1;
+
+ error = mmc_host_init(dev);
+ if (error) {
+ printf("mmc_host_init() %d \n", error);
+ return -1;
+ }
+ mmc_register(dev);
+ debug("registered mmc/sd interface number is:%d\n",
+ dev->block_dev.dev);
+
+ return 0;
+}
diff --git a/board/st/u8500/mmc_host.h b/board/st/u8500/mmc_host.h
new file mode 100644
index 000000000..644f01b37
--- /dev/null
+++ b/board/st/u8500/mmc_host.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com>
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __MMC_NOMADIK_H__
+#define __MMC_NOMADIK_H__
+
+/* See SDI (SD card host interface) documentation in U8500 sw specification. */
+
+#define COMMAND_REG_DELAY 300
+#define DATA_REG_DELAY 1000
+#define CLK_CHANGE_DELAY 2000
+
+#define MAX_ERROR_VALUE -65
+enum mmc_result {
+ /* MMC specific error defines */
+ MMC_CMD_CRC_FAIL = (MAX_ERROR_VALUE - 1),/* Command response received
+ (but CRC check failed) */
+ MMC_DATA_CRC_FAIL = (MAX_ERROR_VALUE - 2),/* Data bock sent/received
+ (CRC check Failed) */
+ MMC_CMD_RSP_TIMEOUT = (MAX_ERROR_VALUE - 3),/*Command response timeout
+ */
+ MMC_DATA_TIMEOUT = (MAX_ERROR_VALUE - 4),/* Data time out*/
+ MMC_TX_UNDERRUN = (MAX_ERROR_VALUE - 5),/* Transmit FIFO under-run */
+ MMC_RX_OVERRUN = (MAX_ERROR_VALUE - 6), /* Receive FIFO over-run */
+ MMC_START_BIT_ERR = (MAX_ERROR_VALUE - 7),/* Start bit not detected on
+ all data signals in widE bus mode */
+ MMC_CMD_OUT_OF_RANGE = (MAX_ERROR_VALUE - 8),/* CMD's argument was out
+ of range.*/
+ MMC_ADDR_MISALIGNED = (MAX_ERROR_VALUE - 9),/* Misaligned address */
+ MMC_BLOCK_LEN_ERR = (MAX_ERROR_VALUE - 10),/* Transferred block length
+ is not allowed for the card or the number of
+ transferred bytes does not match the block length*/
+ MMC_ERASE_SEQ_ERR = (MAX_ERROR_VALUE - 11),/* An error in the sequence
+ of erase command occurs.*/
+ MMC_BAD_ERASE_PARAM = (MAX_ERROR_VALUE - 12),/* An Invalid selection
+ for erase groups */
+ MMC_WRITE_PROT_VIOLATION = (MAX_ERROR_VALUE - 13),/* Attempt to program
+ a write protect block */
+ MMC_LOCK_UNLOCK_FAILED = (MAX_ERROR_VALUE - 14),/* Sequence or password
+ error has been detected in unlock command or
+ if there was an attempt to access a locked card */
+ MMC_COM_CRC_FAILED = (MAX_ERROR_VALUE - 15),/* CRC check of the
+ previous command failed*/
+ MMC_ILLEGAL_CMD = (MAX_ERROR_VALUE - 16),/* Command is not legal for
+ the card state */
+ MMC_CARD_ECC_FAILED = (MAX_ERROR_VALUE - 17),/* Card internal ECC was
+ applied but failed to correct the data */
+ MMC_CC_ERROR = (MAX_ERROR_VALUE - 18),/*Internal card controller error
+ */
+ MMC_GENERAL_UNKNOWN_ERROR = (MAX_ERROR_VALUE - 19),/* General or
+ Unknown error */
+ MMC_STREAM_READ_UNDERRUN = (MAX_ERROR_VALUE - 20),/* The card could not
+ sustain data transfer in stream read
+ operation. */
+ MMC_STREAM_WRITE_OVERRUN = (MAX_ERROR_VALUE - 21),/* The card could not
+ sustain data programming in stream mode */
+ MMC_CID_CSD_OVERWRITE = (MAX_ERROR_VALUE - 22), /* CID/CSD overwrite
+ error */
+ MMC_WP_ERASE_SKIP = (MAX_ERROR_VALUE - 23),/* only partial address
+ space was erased */
+ MMC_CARD_ECC_DISABLED = (MAX_ERROR_VALUE - 24),/* Command has been
+ executed without using internal ECC */
+ MMC_ERASE_RESET = (MAX_ERROR_VALUE - 25),/* Erase sequence was cleared
+ before executing because an out of erase sequence
+ command was received */
+ MMC_AKE_SEQ_ERROR = (MAX_ERROR_VALUE - 26),/* Error in sequence of
+ authentication. */
+ MMC_INVALID_VOLTRANGE = (MAX_ERROR_VALUE - 27),
+ MMC_ADDR_OUT_OF_RANGE = (MAX_ERROR_VALUE - 28),
+ MMC_SWITCH_ERROR = (MAX_ERROR_VALUE - 29),
+ MMC_SDIO_DISABLED = (MAX_ERROR_VALUE - 30),
+ MMC_SDIO_FUNCTION_BUSY = (MAX_ERROR_VALUE - 31),
+ MMC_SDIO_FUNCTION_FAILED = (MAX_ERROR_VALUE - 32),
+ MMC_SDIO_UNKNOWN_FUNCTION = MAX_ERROR_VALUE,
+ /* standard error defines */
+ MMC_INTERNAL_ERROR = -8,
+ MMC_NOT_CONFIGURED = -7,
+ MMC_REQUEST_PENDING = -6,
+ MMC_REQUEST_NOT_APPLICABLE = -5,
+ MMC_INVALID_PARAMETER = -4,
+ MMC_UNSUPPORTED_FEATURE = -3,
+ MMC_UNSUPPORTED_HW = -2,
+ MMC_ERROR = -1,
+ MMC_OK = 0,
+ MMC_INTERNAL_EVENT = 1,
+ MMC_REMAINING_PENDING_EVENTS = 2,
+ MMC_REMAINING_FILTER_PENDING_EVENTS = 3,
+ MMC_NO_MORE_PENDING_EVENT = 4,
+ MMC_NO_MORE_FILTER_PENDING_EVENT = 5,
+ MMC_NO_PENDING_EVENT_ERROR = 7,
+};
+
+#define MCLK (100*1000*1000)
+
+#define INDEX(mask) ( \
+ ((mask & 0x00000001) ? 0 : \
+ ((mask & 0x00000002) ? 1 : \
+ ((mask & 0x00000004) ? 2 : \
+ ((mask & 0x00000008) ? 3 : \
+ ((mask & 0x00000010) ? 4 : \
+ ((mask & 0x00000020) ? 5 : \
+ ((mask & 0x00000040) ? 6 : \
+ ((mask & 0x00000080) ? 7 : \
+ ((mask & 0x00000100) ? 8 : \
+ ((mask & 0x00000200) ? 9 : \
+ ((mask & 0x00000400) ? 10 : \
+ ((mask & 0x00000800) ? 11 : \
+ ((mask & 0x00001000) ? 12 : \
+ ((mask & 0x00002000) ? 13 : \
+ ((mask & 0x00004000) ? 14 : \
+ ((mask & 0x00008000) ? 15 : \
+ ((mask & 0x00010000) ? 16 : \
+ ((mask & 0x00020000) ? 17 : \
+ ((mask & 0x00040000) ? 18 : \
+ ((mask & 0x00080000) ? 19 : \
+ ((mask & 0x00100000) ? 20 : \
+ ((mask & 0x00200000) ? 21 : \
+ ((mask & 0x00400000) ? 22 : \
+ ((mask & 0x00800000) ? 23 : \
+ ((mask & 0x01000000) ? 24 : \
+ ((mask & 0x02000000) ? 25 : \
+ ((mask & 0x04000000) ? 26 : \
+ ((mask & 0x08000000) ? 27 : \
+ ((mask & 0x10000000) ? 28 : \
+ ((mask & 0x20000000) ? 29 : \
+ ((mask & 0x40000000) ? 30 : \
+ ((mask & 0x80000000) ? 31 : 0) \
+ ))))))))))))))))))))))))))))))) \
+)
+
+#define MMC_PERIPHERAL_ID0 0x81
+#define MMC_PERIPHERAL_ID1 0x11
+#define MMC_PERIPHERAL_ID2 0x04
+#define MMC_PERIPHERAL_ID3 0x00
+
+/* SDI Power Control register bits */
+
+#define SDI_PWR_PWRCTRL_MASK (0x00000003)
+#define SDI_PWR_PWRCTRL_ON (0x00000003)
+#define SDI_PWR_PWRCTRL_OFF (0x00000000)
+#define SDI_PWR_DAT2DIREN (0x00000004)
+#define SDI_PWR_CMDDIREN (0x00000008)
+#define SDI_PWR_DAT0DIREN (0x00000010)
+#define SDI_PWR_DAT31DIREN (0x00000020)
+#define SDI_PWR_OPD (0x00000040)
+#define SDI_PWR_FBCLKEN (0x00000080)
+#define SDI_PWR_DAT74DIREN (0x00000100)
+#define SDI_PWR_RSTEN (0x00000200)
+
+#define VOLTAGE_WINDOW_MMC (0x00FF8080)
+#define VOLTAGE_WINDOW_SD (0x80010000)
+
+/* SDI clock control register bits */
+
+#define SDI_CLKCR_CLKDIV_MASK (0x000000FF)
+#define SDI_CLKCR_CLKEN (0x00000100)
+#define SDI_CLKCR_PWRSAV (0x00000200)
+#define SDI_CLKCR_BYPASS (0x00000400)
+#define SDI_CLKCR_WIDBUS_MASK (0x00001800)
+#define SDI_CLKCR_WIDBUS_1 (0x00000000)
+#define SDI_CLKCR_WIDBUS_4 (0x00000800)
+#define SDI_CLKCR_WIDBUS_8 (0x00001000)
+#define SDI_CLKCR_NEGEDGE (0x00002000)
+#define SDI_CLKCR_HWFC_EN (0x00004000)
+
+#define SDI_CLKCR_CLKDIV_INIT (0x000000FD)
+
+/* SDI command register bits */
+
+#define SDI_CMD_CMDINDEX_MASK (0x000000FF)
+#define SDI_CMD_WAITRESP (0x00000040)
+#define SDI_CMD_LONGRESP (0x00000080)
+#define SDI_CMD_WAITINT (0x00000100)
+#define SDI_CMD_WAITPEND (0x00000200)
+#define SDI_CMD_CPSMEN (0x00000400)
+#define SDI_CMD_SDIOSUSPEND (0x00000800)
+#define SDI_CMD_ENDCMDCOMPL (0x00001000)
+#define SDI_CMD_NIEN (0x00002000)
+#define SDI_CMD_CE_ATACMD (0x00004000)
+#define SDI_CMD_CBOOTMODEEN (0x00008000)
+
+#define SDI_DTIMER_DEFAULT (0xFFFF0000)
+
+/* SDI Status register bits */
+
+#define SDI_STA_CCRCFAIL (0x00000001) /* (1 << 0) */
+#define SDI_STA_DCRCFAIL (0x00000002) /* (1 << 1) */
+#define SDI_STA_CTIMEOUT (0x00000004) /* (1 << 2) */
+#define SDI_STA_DTIMEOUT (0x00000008) /* (1 << 3) */
+#define SDI_STA_TXUNDERR (0x00000010) /* (1 << 4) */
+#define SDI_STA_RXOVERR (0x00000020) /* (1 << 5) */
+#define SDI_STA_CMDREND (0x00000040) /* (1 << 6) */
+#define SDI_STA_CMDSENT (0x00000080) /* (1 << 7) */
+#define SDI_STA_DATAEND (0x00000100) /* (1 << 8) */
+#define SDI_STA_STBITERR (0x00000200) /* (1 << 9) */
+#define SDI_STA_DBCKEND (0x00000400) /* (1 << 10) */
+#define SDI_STA_CMDACT (0x00000800) /* (1 << 11) */
+#define SDI_STA_TXACT (0x00001000) /* (1 << 12) */
+#define SDI_STA_RXACT (0x00002000) /* (1 << 13) */
+#define SDI_STA_TXFIFOBW (0x00004000) /* (1 << 14) */
+#define SDI_STA_RXFIFOBR (0x00008000) /* (1 << 15) */
+#define SDI_STA_TXFIFOF (0x00010000) /* (1 << 16) */
+#define SDI_STA_RXFIFOF (0x00020000) /* (1 << 17) */
+#define SDI_STA_TXFIFOE (0x00040000) /* (1 << 18) */
+#define SDI_STA_RXFIFOE (0x00080000) /* (1 << 19) */
+#define SDI_STA_TXDAVL (0x00100000) /* (1 << 20) */
+#define SDI_STA_RXDAVL (0x00200000) /* (1 << 21) */
+#define SDI_STA_SDIOIT (0x00400000) /* (1 << 22) */
+#define SDI_STA_CEATAEND (0x00800000) /* (1 << 23) */
+#define SDI_STA_CARDBUSY (0x01000000) /* (1 << 24) */
+#define SDI_STA_BOOTMODE (0x02000000) /* (1 << 25) */
+#define SDI_STA_BOOTACKERR (0x04000000) /* (1 << 26) */
+#define SDI_STA_BOOTACKTIMEOUT (0x08000000) /* (1 << 27) */
+#define SDI_STA_RSTNEND (0x10000000) /* (1 << 28) */
+
+/* SDI Interrupt Clear register bits */
+
+#define SDI_ICR_MASK (0x1DC007FF)
+#define SDI_ICR_CCRCFAILC (0x00000001) /* (1 << 0) */
+#define SDI_ICR_DCRCFAILC (0x00000002) /* (1 << 1) */
+#define SDI_ICR_CTIMEOUTC (0x00000004) /* (1 << 2) */
+#define SDI_ICR_DTIMEOUTC (0x00000008) /* (1 << 3) */
+#define SDI_ICR_TXUNDERRC (0x00000010) /* (1 << 4) */
+#define SDI_ICR_RXOVERRC (0x00000020) /* (1 << 5) */
+#define SDI_ICR_CMDRENDC (0x00000040) /* (1 << 6) */
+#define SDI_ICR_CMDSENTC (0x00000080) /* (1 << 7) */
+#define SDI_ICR_DATAENDC (0x00000100) /* (1 << 8) */
+#define SDI_ICR_STBITERRC (0x00000200) /* (1 << 9) */
+#define SDI_ICR_DBCKENDC (0x00000400) /* (1 << 10) */
+#define SDI_ICR_SDIOITC (0x00400000) /* (1 << 22) */
+#define SDI_ICR_CEATAENDC (0x00800000) /* (1 << 23) */
+#define SDI_ICR_BUSYENDC (0x01000000) /* (1 << 24) */
+#define SDI_ICR_BOOTACKERRC (0x04000000) /* (1 << 26) */
+#define SDI_ICR_BOOTACKTIMEOUTC (0x08000000) /* (1 << 27) */
+#define SDI_ICR_RSTNENDC (0x10000000) /* (1 << 28) */
+
+#define SDI_MASK0_MASK (0x1FFFFFFF)
+
+/* SDI Data control register bits */
+
+#define SDI_DCTRL_DTEN (0x00000001) /* (1 << 0) */
+#define SDI_DCTRL_DTDIR_IN (0x00000002) /* (1 << 1) */
+#define SDI_DCTRL_DTMODE_STREAM (0x00000004) /* (1 << 2) */
+#define SDI_DCTRL_DMAEN (0x00000008) /* (1 << 3) */
+#define SDI_DCTRL_DBLOCKSIZE_MASK (0x000000F0)
+#define SDI_DCTRL_RWSTART (0x00000100) /* (1 << 8) */
+#define SDI_DCTRL_RWSTOP (0x00000200) /* (1 << 9) */
+#define SDI_DCTRL_RWMOD (0x00000200) /* (1 << 10) */
+#define SDI_DCTRL_SDIOEN (0x00000800) /* (1 << 11) */
+#define SDI_DCTRL_DMAREQCTL (0x00001000) /* (1 << 12) */
+#define SDI_DCTRL_DBOOTMODEEN (0x00002000) /* (1 << 13) */
+#define SDI_DCTRL_BUSYMODE (0x00004000) /* (1 << 14) */
+#define SDI_DCTRL_DDR_MODE (0x00008000) /* (1 << 15) */
+
+#define SDI_FIFO_BURST_SIZE (8)
+
+struct sdi_registers {
+ u32 power; /* 0x00*/
+ u32 clock; /* 0x04*/
+ u32 argument; /* 0x08*/
+ u32 command; /* 0x0c*/
+ u32 respcommand; /* 0x10*/
+ u32 response0; /* 0x14*/
+ u32 response1; /* 0x18*/
+ u32 response2; /* 0x1c*/
+ u32 response3; /* 0x20*/
+ u32 datatimer; /* 0x24*/
+ u32 datalength; /* 0x28*/
+ u32 datactrl; /* 0x2c*/
+ u32 datacount; /* 0x30*/
+ u32 status; /* 0x34*/
+ u32 status_clear; /* 0x38*/
+ u32 mask0; /* 0x3c*/
+ u32 mask1; /* 0x40*/
+ u32 card_select; /* 0x44*/
+ u32 fifo_count; /* 0x48*/
+ u32 padding1[(0x80-0x4C)>>2];
+ u32 fifo; /* 0x80*/
+ u32 padding2[(0xFE0-0x84)>>2];
+ u32 periph_id0; /* 0xFE0 mmc Peripheral Identi.cation Register*/
+ u32 periph_id1; /* 0xFE4*/
+ u32 periph_id2; /* 0xFE8*/
+ u32 periph_id3; /* 0xFEC*/
+ u32 pcell_id0; /* 0xFF0*/
+ u32 pcell_id1; /* 0xFF4*/
+ u32 pcell_id2; /* 0xFF8*/
+ u32 pcell_id3; /* 0xFFC*/
+};
+
+#endif
diff --git a/board/st/u8500/mmc_p.h b/board/st/u8500/mmc_p.h
deleted file mode 100755
index e32701f3e..000000000
--- a/board/st/u8500/mmc_p.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-#ifndef _MMC_P_H_
-#define _MMC_P_H_
-
-#define BIT31 0x80000000
-#define PROCESSOR_CLK 200000000
-#define MAXBSIZEPOWER 11
-
-#define MCLK 26000000
-
-#define MMC_PERIPHERAL_ID0 0x81
-#define MMC_PERIPHERAL_ID1 0x11
-#define MMC_PERIPHERAL_ID2 0x04
-#define MMC_PERIPHERAL_ID3 0x00
-
-
-#define MMC_PCELL_ID0 0x0D
-#define MMC_PCELL_ID1 0xF0
-#define MMC_PCELL_ID2 0x05
-#define MMC_PCELL_ID3 0xB1
-
-
-typedef volatile struct {
- u32 mmc_Power; // 0x00
- u32 mmc_Clock; // 0x04
- u32 mmc_Argument; // 0x08
- u32 mmc_Command; // 0x0c
- u32 mmc_RespCommand; // 0x10
- u32 mmc_Response0; // 0x14
- u32 mmc_Response1; // 0x18
- u32 mmc_Response2; // 0x1c
- u32 mmc_Response3; // 0x20
- u32 mmc_DataTimer; // 0x24
- u32 mmc_DataLength; // 0x28
- u32 mmc_DataCtrl; // 0x2c
- u32 mmc_DataCnt; // 0x30
- u32 mmc_Status; // 0x34
- u32 mmc_Clear; // 0x38
- u32 mmc_Mask0; // 0x3c
- u32 mmc_Mask1; // 0x40
- u32 mmc_SelectSD; // 0x44
- u32 mmc_FifoCnt; // 0x48
- u32 mmc_unused1[(0x80-0x4C)>>2];
- u32 mmc_Fifo; // 0x80
- u32 mmc_unused2[(0xFE0-0x84)>>2];
- u32 mmc_PeriphId0; // 0xFE0 mmc Peripheral Identi.cation Register
- u32 mmc_PeriphId1; // 0xFE4
- u32 mmc_PeriphId2; // 0xFE8
- u32 mmc_PeriphId3; // 0xFEC
-
- u32 mmc_PCellId0; // 0xFF0 mmc PCell Identi.cation Register
- u32 mmc_PCellId1; // 0xFF4
- u32 mmc_PCellId2; // 0xFF8
- u32 mmc_PCellId3; // 0xFFc
-}t_mmc_register;
-
-
-// Elementary layer
-#define BIT_MASK(__bws) ((u32)(((wb ## __bws)==32)?0xFFFFFFFF:\
- ((1U << (wb ## __bws)) - 1)) << (sb ## __bws))
-
-#define MMC_WRITE_BITS(reg,val,mask,sb) ((reg) = (((reg) & ~(mask)) | (((val)<<(sb)) & (mask))))
-#define MMC_READ_BITS(reg,mask,sb) ((reg & mask)>>sb)
-
-#define wbMMC_Power_CTRL 2
-#define sbMMC_Power_CTRL 0
-#define MMC_Power_MASK_CTRL BIT_MASK(MMC_Power_CTRL)
-
-#define wbMMC_Power_VOLT 4
-#define sbMMC_Power_VOLT 2
-#define MMC_Power_MASK_VOLT BIT_MASK(MMC_Power_VOLT)
-
-#define wbMMC_Power_OPEND 1
-#define sbMMC_Power_OPEND 6
-#define MMC_Power_MASK_OPEND BIT_MASK(MMC_Power_OPEND)
-
-#define wbMMC_Power_ROD 1
-#define sbMMC_Power_ROD 7
-#define MMC_Power_MASK_ROD BIT_MASK(MMC_Power_ROD)
-
-#define wbMMC_Clock_CLKDIV 8
-#define sbMMC_Clock_CLKDIV 0
-#define MMC_Clock_MASK_CLKDIV BIT_MASK(MMC_Clock_CLKDIV)
-
-#define wbMMC_Clock_ENABLE 1
-#define sbMMC_Clock_ENABLE 8
-#define MMC_Clock_MASK_ENABLE BIT_MASK(MMC_Clock_ENABLE)
-
-#define wbMMC_Clock_PWRSAVE 1
-#define sbMMC_Clock_PWRSAVE 9
-#define MMC_Clock_MASK_PWRSAVE BIT_MASK(MMC_Clock_PWRSAVE)
-
-#define wbMMC_Clock_BYPASS 1
-#define sbMMC_Clock_BYPASS 10
-#define MMC_Clock_MASK_BYPASS BIT_MASK(MMC_Clock_BYPASS)
-
-#define wbMMC_Clock_WIDEBUS 1
-#define sbMMC_Clock_WIDEBUS 11
-#define MMC_Clock_MASK_WIDEBUS BIT_MASK(MMC_Clock_WIDEBUS)
-#define MMC_SET_WIDEBUS(reg,a) MMC_WRITE_BITS(reg,a,MMC_Clock_MASK_WIDEBUS,sbMMC_Clock_WIDEBUS)
-
-#define wbMMC_DataPath_ENABLE 1
-#define sbMMC_DataPath_ENABLE 0
-#define MMC_DataPath_MASK_ENABLE BIT_MASK(MMC_DataPath_ENABLE)
-
-#define wbMMC_DataPath_BLOCKSIZE 4
-#define sbMMC_DataPath_BLOCKSIZE 4
-#define MMC_DataPath_MASK_BLOCKSIZE BIT_MASK(MMC_DataPath_BLOCKSIZE)
-
-#define wbMMC_DataPath_DIRECTION 1
-#define sbMMC_DataPath_DIRECTION 1
-#define MMC_DataPath_MASK_DIRECTION BIT_MASK(MMC_DataPath_DIRECTION)
-
-#define wbMMC_DataPath_MODE 1
-#define sbMMC_DataPath_MODE 2
-#define MMC_DataPath_MASK_MODE BIT_MASK(MMC_DataPath_MODE)
-
-#define wbMMC_DataPath_DMA 1
-#define sbMMC_DataPath_DMA 3
-#define MMC_DataPath_MASK_DMA BIT_MASK(MMC_DataPath_DMA)
-
-#define MMC_SET_CTRL(reg,a) MMC_WRITE_BITS(reg,a,MMC_Power_MASK_CTRL,sbMMC_Power_CTRL)
-#define MMC_SET_VOLT(reg,a) MMC_WRITE_BITS(reg,a,MMC_Power_MASK_VOLT,sbMMC_Power_VOLT)
-#define MMC_SET_OPEND(reg,a) MMC_WRITE_BITS(reg,a,MMC_Power_MASK_OPEND,sbMMC_Power_OPEND)
-#define MMC_SET_ROD(reg,a) MMC_WRITE_BITS(reg,a,MMC_Power_MASK_ROD,sbMMC_Power_ROD)
-#define MMC_SET_CENABLE(reg,a) MMC_WRITE_BITS(reg,a,MMC_Clock_MASK_ENABLE,sbMMC_Clock_ENABLE)
-#define MMC_SET_PWRSAVE(reg,a) MMC_WRITE_BITS(reg,a,MMC_Clock_MASK_PWRSAVE,sbMMC_Clock_PWRSAVE)
-#define MMC_SET_BYPASS(reg,a) MMC_WRITE_BITS(reg,a,MMC_Clock_MASK_BYPASS,sbMMC_Clock_BYPASS)
-
-#define MMC_SET_CLKDIV(reg,a) MMC_WRITE_BITS(reg,a,MMC_Clock_MASK_CLKDIV,sbMMC_Clock_CLKDIV)
-#define MMC_SET_DATAPATH(reg,a) MMC_WRITE_BITS(reg,a,MMC_DataPath_MASK_ENABLE,sbMMC_DataPath_ENABLE)
-#define MMC_SET_BLOCKSIZE(reg,a) MMC_WRITE_BITS(reg,a,MMC_DataPath_MASK_BLOCKSIZE,sbMMC_DataPath_BLOCKSIZE)
-#define MMC_SET_DATADIR(reg,a) MMC_WRITE_BITS(reg,a,MMC_DataPath_MASK_DIRECTION,sbMMC_DataPath_DIRECTION)
-#define MMC_SET_MODE(reg,a) MMC_WRITE_BITS(reg,a,MMC_DataPath_MASK_MODE,sbMMC_DataPath_MODE)
-#define MMC_SET_DMA(reg,a) MMC_WRITE_BITS(reg,a,MMC_DataPath_MASK_DMA,sbMMC_DataPath_DMA)
-
-
-
-// Functional layer
-#define R1_OUT_OF_RANGE 0x80000000
-#define R1_ADDRESS_ERROR 0x40000000
-#define R1_BLOCK_LEN_ERROR 0x20000000
-#define R1_ERASE_SEQ_ERROR 0x10000000
-#define R1_ERASE_PARAM 0x08000000
-#define R1_WP_VIOLATION 0x04000000
-#define R1_CARD_IS_LOCKED 0x02000000
-#define R1_LOCK_UNLOCK_FAILED 0x01000000
-#define R1_COM_CRC_ERROR 0x00800000
-#define R1_ILLEGAL_COMMAND 0x00400000
-#define R1_CARD_ECC_FAILED 0x00200000
-#define R1_CC_ERROR 0x00100000
-#define R1_UNKNOWN_ERROR 0x00080000
-#define R1_STREAM_READ_UNDERRUN 0x00040000
-#define R1_STREAM_WRITE_OVERRUN 0x00020000
-#define R1_CID_CSD_OVERWRITE 0x00010000
-#define R1_WP_ERASE_SKIP 0x00008000
-#define R1_CARD_ECC_DISABLED 0x00004000
-#define R1_ERASE_RESET 0x00002000
-#define R1_AKE_SEQ_ERROR 0x00000008
-#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
-#define R1_READY_FOR_DATA 0x000000100
-#define R1_APP_CMD 0x000000020
-
-/* DEFINES FOR R6 RESPONSE */
-#define R6_GEN_UNKNOWN_ERROR 0x00002000
-#define R6_ILLEGAL_CMD 0x00004000
-#define R6_COM_CRC_FAILED 0x00008000
-
-#define AllOne (0xffffffff)
-#define AllZero (0x00000000)
-
-
-//Power Control register
-
-#define PowerOn (0x00000003)
-#define OpenDrain (0x00000040)
-#define CmdDatEn (0x0000003C)
-#define VoltageWindowMMC (0x80FFC000)
-#define VoltageWindowSD (0x80010000)
-#define StuffBits0To32 (0xFFFFFFFF)
-#define StuffBits0To15 (0xFFFF)
-#define Sector_Mode (0x40000000)
-#define Byte_Mode (0x00000000)
-#define Check_Pattern (0x000001AA)
-
-//Clock Control register
-
-#define ClkDivInit (0x00000076)
-#define ClkDivTrans (0x00000001)
-#define ClkEnable (0x00000100)
-#define PwrSave (0x00000200)
-#define Enab_Bypass (0x00000400)
-#define Widebus_4 (0x00000800)
-#define Widebus_8 (0x00001000)
-#define Hwfc_en (0x00004000)
-
-//Command register
-
-//all commands
-
-#define GO_IDLE_STATE (0)
-#define SEND_OP_COND (1)
-#define ALL_SEND_CID (2)
-#define SET_REL_ADDR (3)
-#define SET_DSR (4)
-#define SEL_DESEL_CARD (7)
-#define SEND_EXT_CSD (8)
-#define SEND_CSD (9)
-#define SEND_CID (10)
-#define READ_DAT_UNTIL_STOP (11)
-#define STOP_TRANSMISSION (12)
-#define SEND_STATUS (13)
-#define GO_INACTIVE_STATE (15)
-#define SET_BLOCKLEN (16)
-#define READ_SINGLE_BLOCK (17)
-#define READ_MULT_BLOCK (18)
-#define WRITE_DAT_UNTIL_STOP (20)
-#define SET_BLOCK_COUNT (23)
-#define WRITE_SINGLE_BLOCK (24)
-#define WRITE_MULT_BLOCK (25)
-#define PROG_CID (26)
-#define PROG_CSD (27)
-#define SET_WRITE_PROT (28)
-#define CLR_WRITE_PROT (29)
-#define SEND_WRITE_PROT (30)
-#define ERASE_GRP_START (35)
-#define ERASE_GRP_END (36)
-#define ERASE (38)
-#define FAST_IO (39)
-#define GO_IRQ_STATE (40)
-#define LOCK_UNLOCK (42)
-#define APP_CMD (55)
-#define GEN_CMD (56)
-
-/*Following commands are SD Card Specific commands. MMC_APP_CMD should be sent before sending these commands.*/
-#define APP_SD_SET_BUSWIDTH (6)
-#define SD_APP_STAUS (13)
-#define SD_APP_SEND_NUM_WRITE_BLOCKS (22)
-#define SD_APP_OP_COND (41)
-#define SD_APP_SET_CLR_CARD_DETECT (42)
-#define SD_APP_SEND_SCR (51)
-#define SD_SEND_IF_COND (8)
-
-//Command control register
-
-#define RespExpected (0x00000040)
-#define LongResponse (0x00000080)
-#define EnabIntrReq (0x00000100)
-#define EnabCmdPend (0x00000200)
-#define CmdPathEnable (0x00000400)
-
-
-//Data Control register
-
-#define DataPathEnable (0x00000001)
-#define ReadDir (0x00000002)
-#define StreamMode (0x00000004)
-#define DMAEnab (0x00000008)
-#define BlockSize (0x000000F0)
-
-//Status register
-
-#define CmdCrcFail (0x00000001)
-#define DataCrcFail (0x00000002)
-#define CmdTimeOut (0x00000004)
-#define DataTimeOut (0x00000008)
-#define TxUnderrun (0x00000010)
-#define RxOverrun (0x00000020)
-#define CmdRespEnd (0x00000040)
-#define CmdSent (0x00000080)
-#define DataEnd (0x00000100)
-#define StartBitError (0x00000200)
-#define DataBlockEnd (0x00000400)
-#define CmdActive (0x00000800)
-#define TxActive (0x00001000)
-#define RxActive (0x00002000)
-#define TxFifoHalfEmpty (0x00004000)
-#define RxFifoHalfFull (0x00008000)
-#define TxFifoFull (0x00010000)
-#define RxFifoFull (0x00020000)
-#define TxFifoEmpty (0x00040000)
-#define RxFifoEmpty (0x00080000)
-#define TxDataAvlbl (0x00100000)
-#define RxDataAvlbl (0x00200000)
-#define AllInterrupts (0x003FFDFF)
-#define ErrorBits (0xFDFFE008)
-
-#define ClrStaticFlags (0x00C007FF)
-
-/* COMMAND CLASS SUPPORTED */
-#define CCCC_LOCK_UNLOCK (0x80)
-#define CCCC_WRITE_PROT (0x40)
-#define CCCC_ERASE (0x20)
-
-#endif /*MMCP*/
diff --git a/board/st/u8500/mmc_utils.c b/board/st/u8500/mmc_utils.c
index 5ff34425e..d29255937 100644
--- a/board/st/u8500/mmc_utils.c
+++ b/board/st/u8500/mmc_utils.c
@@ -21,880 +21,138 @@
*/
#include <linux/ctype.h>
-#include <common.h>
+#include "common.h"
#include <command.h>
+#include <mmc.h>
#include <fat.h>
-#include "gpio.h"
-#include "mmc.h" // MMC api
-#include "mmc_utils.h" // to access MMC
-#include "mmc_p.h" // t_mmc_register definition
-u32 MMCBuffer[1024] ;
-static int IS_SD_CARD;
-
-/* --- exported from other modules ---------------------------------------- */
-static u8 selected_card = 0;
-extern t_mmc_error mmc_cmderror_2 (void);
-extern t_mmc_error mmc_cmdresp2error_2 (void);
-extern t_mmc_error mmc_cmdresp3error_2 (void);
-extern t_mmc_error mmc_cmdresp145error_2 (u8 cmd);
-extern t_mmc_error mmc_cmdreadresp (u32 * tempbuff);
-extern t_mmc_error mmc_waitcmdreadresp (void);
-extern t_mmc_error mmc_cmdwriteresp (u8 cardno, u32 * tempbuff, u16 total_num_of_bytes);
-extern t_mmc_error mmc_waitcmdwriteresp (u8 cardno, u32 * tempbuff, u16 total_num_of_bytes);
-
-extern t_mmc_register *t_mmc0;
-extern u32 t_mmc_rel_addr;
-
-t_mmc_boot_record mmc_boot_record;
-
-void mmc_copyByteH (u8 * sourceAddr, u8 * destAddress, int size)
-{
- int i;
- for (i = 0; i < size; i++)
- {
- *(destAddress + i) = *(sourceAddr + i);
- }
-}
-
-void mmc_shift_memH (int num_of_words, u32 * start_address, u32 * dest_address, u32 shift)
-{
- u32 *address;
- int word = 0;
- u32 high;
- int i, word_offset, bit_offset;
-
- word_offset = (int) (shift / 32);
- bit_offset = (int) (shift % 32);
- for (i = 0; i < num_of_words; i++)
- {
- *(dest_address + i) = 0;
- }
- for (i = word_offset; i < num_of_words; i++)
- {
- *(dest_address + i - word_offset) = *(start_address + i);
- }
- address = dest_address;
- for (word = 0; word < num_of_words - 1; word++)
- {
- *address = (*address) >> bit_offset;
- address++;
- high = (*address << (32 - bit_offset));
- *(address - 1) |= high;
- }
- *address = (*address) >> bit_offset;
-}
-
-u8 convert_from_bytes_to_power_of_two (u16 no_of_bytes)
-{
- u8 count = 0;
- while (no_of_bytes != 1)
- {
- no_of_bytes >>= 1;
- count++;
- }
- return count;
-}
-
-t_mmc_error mmc_enable ()
-{
- t_mmc_error error = MMC_OK;
- t_mmc_command_control commcontrol;
- t_bool validvoltage = FALSE;
- u32 arg, response;
- int i;
-
- IS_SD_CARD = 0;
-
- selected_card = 0;
-
- t_mmc0->mmc_Power = 0x1BF;
- t_mmc0->mmc_Clock = 0x41FF;
-
- commcontrol.IsRespExpected = FALSE;
- commcontrol.IsLongResp = FALSE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_sendcommand (MMC_GO_IDLE_STATE, 0x00000000, commcontrol);
-
- error = mmc_cmderror_2 ();
-
- //// Added by Chris Sebastian for SD Card support:
- //// Send ACMD41. If we do not get a response, it is not an SD card.
- //// If we do get a response, loop until card is not busy.
-
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = FALSE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- for(i = 200; i; i--) {
- error = mmc_sendcommand (MMC_APP_CMD, 0x00000000, commcontrol); // Let the card know that the next command is an app-cmd.
- error = mmc_cmdresp145error_2(MMC_APP_CMD);
- error = mmc_sendcommand (SD_SEND_OP_COND, 0x00060000, commcontrol); // I got the 0x00060000 from Linux kernel source.
- error = mmc_cmdresp3error_2 ();
- t_mmc0->mmc_Clear = ClrStaticFlags; //clear all the static status flags. CmdResp3Error_2 leaves some bits set.
- if (t_mmc0->mmc_Response0 & 0x80000000) {
- printf("SD card detected \n");
- IS_SD_CARD = 1;
- return MMC_OK; // SD CARD DETECTED. Do not continue with MMC init logic. Quick escape!
- }
- }
-
- commcontrol.IsRespExpected = FALSE;
- commcontrol.IsLongResp = FALSE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_sendcommand (MMC_GO_IDLE_STATE, 0x00000000, commcontrol);
- error = mmc_cmderror_2 ();
-
- arg = 0x00060000; // High Voltage MMC, byte mode. Was 0x00FFC000, but that writes to reserved bits...
- while (!validvoltage)
- {
- // send CMD1 (SEND_OP_COND)
- commcontrol.IsRespExpected = TRUE;
- error = mmc_sendcommand (MMC_SEND_OP_COND, arg, commcontrol);
-
- error = mmc_cmdresp3error_2 ();
-
- if (error != MMC_OK)
- {
- goto end;
- }
- mmc_getresponse (MMC_SHORT_RESP, &response);
-
- arg = response;
- validvoltage = (t_bool) (((response >> 31) == 1) ? 1 : 0);
-
- }
-end:
- return error;
-}
-
-t_mmc_error mmc_disable ()
-{
- t_mmc_error error = MMC_OK;
- t_mmc_power_state powerstate = MMC_POWER_OFF;
-
- error = mmc_setpowerstate (powerstate);
- return error;
-}
-
-t_mmc_error mmc_initCard ()
-{
- t_mmc_error error = MMC_OK;
- t_mmc_command_control commcontrol;
- t_mmc_bus_configuration busconfig;
- t_mmc_clock_control clockcontrol;
-
- // send CMD2 (ALL_SEND_CID)
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = TRUE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_sendcommand (MMC_ALL_SEND_CID, 0x00000000, commcontrol);
- error = mmc_cmdresp2error_2 ();
- // error is MMC_CMD_CRC_FAIL on COB board ?!
- // if( error != MMC_OK)
- // goto end;
-
- // send CMD3 (SET_RELATIVE_ADDR)
-
- commcontrol.IsLongResp = FALSE;
- error = mmc_sendcommand (MMC_SET_REL_ADDR, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_SET_REL_ADDR);
- if(IS_SD_CARD) {
- t_mmc_rel_addr = t_mmc0->mmc_Response0 & 0xFFFF0000;
- }
-
- if (error != MMC_OK)
- {
- goto end;
- }
- busconfig.mode = MMC_PUSH_PULL;
- busconfig.rodctrl = MMC_DISABLE;
- error = mmc_configbus (busconfig);
- clockcontrol.pwrsave= MMC_DISABLE;
- clockcontrol.bypass = MMC_DISABLE;
- clockcontrol.widebus= MMC_DISABLE;
- error = mmc_setclockfrequency(0x00); /* 26 MHz */
- if (error != MMC_OK)
- {
- goto end;
- }
- error = mmc_configclockcontrol (clockcontrol);
- if (error != MMC_OK)
- {
- goto end;
- }
-end:
- return error;
-}
-
-t_mmc_error mmc_readblock (u8 cardno, u32 addr, u32 * readbuff, u16 blocksize, t_mmc_transfer_mode mmc_transfer_mode)
-{
- t_mmc_error error = MMC_OK;
- u8 power;
- t_mmc_command_control commcontrol;
- u32 response;
-
- commcontrol.IsRespExpected = TRUE ;
- commcontrol.IsLongResp = FALSE ;
- commcontrol.IsInterruptMode = FALSE ;
- commcontrol.IsPending = FALSE ;
- commcontrol.cmdpath = MMC_ENABLE ;
- error = mmc_setdatapath (MMC_DISABLE);
- error = mmc_handledma (MMC_DISABLE);
- if (error != MMC_OK)
- {
- goto end;
- }
- // send command for selecting the card
- if (cardno != selected_card)
- {
- error = mmc_sendcommand (MMC_SEL_DESEL_CARD, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_SEL_DESEL_CARD);
- if (error != MMC_OK)
- {
- goto end;
- }
- else
- {
- selected_card = cardno;
- }
- }
- error = mmc_getresponse (MMC_SHORT_RESP, &response);
- if (response & 0x02000000)
- {
- return MMC_LOCK_UNLOCK_FAILED;
- }
- // set the block size,both on controller and card
- if ((blocksize > 0) && (blocksize <= 2048) && ((blocksize & (blocksize - 1)) == 0))
- {
- power = convert_from_bytes_to_power_of_two (blocksize);
- error = mmc_setdatablocklength (power);
- error = mmc_sendcommand (MMC_SET_BLOCKLEN, (u32) blocksize, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_SET_BLOCKLEN);
- if (error != MMC_OK)
- {
- return error;
- }
- }
- else
- {
- error = MMC_INVALID_PARAMETER;
- goto end;
- }
- error = mmc_setdatalength (blocksize );
- error = mmc_setdatatimeout (0xefffffff );
- error = mmc_settransferdirection (MMC_READ );
- error = mmc_settransfertype (MMC_BLOCK );
- error = mmc_setdatapath (MMC_ENABLE);
- //t_mmc0->mmc_DataCtrl |= (ReadDir & ~StreamMode) | DataPathEnable;
- error = mmc_sendcommand (MMC_READ_SINGLE_BLOCK, addr, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_READ_SINGLE_BLOCK);
- if (error != MMC_OK)
- {
- goto end;
- }
- if (mmc_transfer_mode == MMCDMA)
- {
- error = mmc_waitcmdreadresp ();
- }
- else
- {
- error = mmc_cmdreadresp (readbuff);
- }
- if (error != MMC_OK)
- {
- goto end;
- }
-end:
- return error;
-}
-
-t_mmc_error mmc_writeblock (u8 cardno, u32 addr, u32 * writebuff, u16 blocksize, t_mmc_transfer_mode mmc_transfer_mode)
-{
- t_mmc_error error = MMC_OK;
- u8 power;
- t_mmc_command_control commcontrol;
- u32 response;
-
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = FALSE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_setdatapath (MMC_DISABLE);
- error = mmc_handledma (MMC_DISABLE);
- error = mmc_settransferdirection(MMC_WRITE);
- error = mmc_settransfertype (MMC_BLOCK);
-
- if (cardno != selected_card)
- {
- error = mmc_sendcommand (MMC_SEL_DESEL_CARD, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_SEL_DESEL_CARD);
- if (error != MMC_OK)
- {
- goto end;
- }
- else
- {
- selected_card = cardno;
- }
- }
-
- mmc_getresponse (MMC_SHORT_RESP, &response);
- if (response & 0x02000000)
- {
- return MMC_LOCK_UNLOCK_FAILED;
- }
- // set the block size,both on controller and card
- if ((blocksize > 0) && (blocksize <= 2048) && (((blocksize & (blocksize - 1)) == 0)))
- {
- power = convert_from_bytes_to_power_of_two (blocksize);
- error = mmc_setdatablocklength (power);
- error = mmc_sendcommand (MMC_SET_BLOCKLEN, (u32) blocksize, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_SET_BLOCKLEN);
- if (error != MMC_OK)
- {
- goto end;
- }
- }
- else
- {
- error = MMC_INVALID_PARAMETER;
- goto end;
- }
-
- error = mmc_setdatalength (blocksize);
- error = mmc_setdatatimeout (0xefffffff);
- error = mmc_settransferdirection (MMC_WRITE);
- error = mmc_settransfertype (MMC_BLOCK);
- error = mmc_setdatapath (MMC_ENABLE);
- error = mmc_sendcommand (MMC_WRITE_SINGLE_BLOCK, addr, commcontrol);
- error = mmc_cmdresp145error_2 (MMC_WRITE_SINGLE_BLOCK);
- if (error != MMC_OK)
- {
- goto end;
- }
- if (mmc_transfer_mode == MMCDMA)
- {
- error = mmc_waitcmdwriteresp (cardno, writebuff, blocksize);
- }
- else
- {
- error = mmc_cmdwriteresp (cardno, writebuff, blocksize);
- }
- if (error != MMC_OK)
- {
- goto end;
- }
-end:
- return error;
-}
-
-t_mmc_error mmc_readcsd (u32 * CSD)
-{
- t_mmc_error error = MMC_OK;
- t_mmc_command_control commcontrol;
- u32 buf[4];
-
- // send CMD9 (SEND CSD)
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = TRUE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_sendcommand (MMC_SEND_CSD, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp2error_2 ();
- if (error != MMC_OK)
- {
- goto end;
- }
- error = mmc_getresponse (MMC_LONG_RESP, buf);
- CSD[0] = buf[3];
- CSD[1] = buf[2];
- CSD[2] = buf[1];
- CSD[3] = buf[0];
-end:
- return error;
-}
-
-t_mmc_error mmc_select_n_switch(void)
+#define PIB_EMMC_ADDR 0x00
+
+struct partition {
+ unsigned char boot_ind; /* 0x80 - active */
+ unsigned char head; /* starting head */
+ unsigned char sector; /* starting sector */
+ unsigned char cyl; /* starting cylinder */
+ unsigned char sys_ind; /* What partition type */
+ unsigned char end_head; /* end head */
+ unsigned char end_sector; /* end sector */
+ unsigned char end_cyl; /* end cylinder */
+ u32 start_sect; /* starting sector counting from 0 */
+ u32 nr_sects; /* nr of sectors in partition */
+} __attribute__((packed));
+
+#define PART(type, start, num) \
+ { \
+ .boot_ind = 0x00, \
+ .head = 0x03, \
+ .sector = 0xD0, \
+ .cyl = 0xff, \
+ .sys_ind = type, \
+ .end_head = 0x03, \
+ .end_sector = 0xd0, \
+ .end_cyl = 0xff, \
+ .start_sect = start, \
+ .nr_sects = num, \
+ }
+
+static struct partition partitions_ed[] = {
+ [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
+ [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
+ [2] = PART(0x83, 0x00124000, 0x0022c000),
+ [3] = PART(0x0c, 0x00350000, 0x00b9a000),
+};
+
+static struct partition partitions_v1[] = {
+ [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
+ [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
+ [2] = PART(0x83, 0x00124000, 0x00000800), /* Modem parameters */
+ [3] = {0},
+};
+
+#undef PART
+
+int write_partition_block(void)
{
- t_mmc_error error = MMC_OK;
- t_mmc_command_control commcontrol;
- /* t_mmc_clock_control clockcontrol; */
- u32 response;
- u8 cardno = 1;
-
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = FALSE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- // send command for selecting the card
- if (cardno != selected_card)
- {
- error = mmc_sendcommand(MMC_SEL_DESEL_CARD, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp145error_2(MMC_SEL_DESEL_CARD);
- if (error != MMC_OK)
- {
- goto end;
- }
- else
- {
- selected_card = cardno;
- }
- }
- error = mmc_getresponse(MMC_SHORT_RESP, &response);
- if (response & 0x02000000)
- {
- error = MMC_LOCK_UNLOCK_FAILED;
- goto end;
- }
- /* XXX: what is this, why is it commented out, why is it here at all? */
- /*
- error = mmc_sendcommand (MMC_APP_CMD, 0x00000000, commcontrol);
- error = mmc_cmdresp145error_2(MMC_APP_CMD);
- error = mmc_sendcommand (6, 0x2, commcontrol);
- error = mmc_cmdresp145error_2(6);
- if (error != MMC_OK)
- {
- goto end;
- }
- clockcontrol.pwrsave= MMC_DISABLE;
- clockcontrol.bypass = MMC_DISABLE;
- clockcontrol.widebus= MMC_ENABLE;
- error = mmc_configclockcontrol (clockcontrol);
- if (error != MMC_OK)
- {
- goto end;
- }
- */
-end:
- return error;
-}
-
-t_mmc_error mmc_readcid (u32 * CID)
-{
- t_mmc_error error = MMC_OK;
- t_mmc_command_control commcontrol;
- u32 buf[4];
-
- // send CMD9 (SEND CSD)
- commcontrol.IsRespExpected = TRUE;
- commcontrol.IsLongResp = TRUE;
- commcontrol.IsInterruptMode = FALSE;
- commcontrol.IsPending = FALSE;
- commcontrol.cmdpath = MMC_ENABLE;
-
- error = mmc_sendcommand (MMC_SEND_CID, t_mmc_rel_addr, commcontrol);
- error = mmc_cmdresp2error_2 ();
- if (error != MMC_OK)
- {
- goto end;
- }
- error = mmc_getresponse (MMC_LONG_RESP, buf);
- CID[0] = buf[3];
- CID[1] = buf[2];
- CID[2] = buf[1];
- CID[3] = buf[0];
-end:
- return error;
+ int err;
+ u32 offset = PIB_EMMC_ADDR;
+ u8 mbr[512];
+ u8 emmc_existing_partition[512];
+ struct mmc *boot_dev = NULL;
+
+ memset(mbr, 0, 0x1be);
+ if (u8500_is_earlydrop())
+ memcpy(mbr + 0x1be, partitions_ed, sizeof(partitions_ed));
+ else
+ memcpy(mbr + 0x1be, partitions_v1, sizeof(partitions_v1));
+
+ /* magic */
+ mbr[0x1fe] = 0x55;
+ mbr[0x1ff] = 0xAA;
+
+ printf("Writing partition block (if needed)...\n");
+
+ boot_dev = find_mmc_device(CONFIG_EMMC_DEV_NUM);
+ if (!boot_dev) {
+ printf(" Error: eMMC device not found\n");
+ return 1;
+ }
+
+ err = boot_dev->block_dev.block_read(CONFIG_EMMC_DEV_NUM,
+ offset,
+ 1,
+ (void *) emmc_existing_partition);
+ if (err != 1) {
+ printf(" Error: eMMC read failed\n");
+ return 1;
+ }
+
+ if (memcmp((void *)emmc_existing_partition, (void *)mbr, 512)) {
+ err = boot_dev->block_dev.block_write(CONFIG_EMMC_DEV_NUM,
+ offset,
+ 1,
+ (void *) mbr);
+ if (err != 1) {
+ printf(" Error: eMMC write failed\n");
+ return 1;
+ }
+ }
+ printf(" eMMC partition block exists now\n");
+ return 0;
}
-t_mmc_error mmc_read_file (char *filename, u32 address, u32 * FileSize)
-{
- u8 *mem_address = (u8 *) address;
- u8 sector[512];
- u16 BytesPerSector;
- u32 BRStartSector;
- u32 FATStartSector;
- u32 DataStartSector;
- u32 FileStartSector;
- u16 SectorsPerFAT;
- u8 SectorsPerCluster;
- u8 k;
- u16 MaxRDEntries;
- u16 ReservedSectors;
- u32 RDStartSector, j;
- char nomefile[12] = " ";
- int filelength;
- u16 FileStartCluster = 0;
- t_mmc_error response, response2;
- int i, goout, found, result = PASS;
- u32 CSD[4];
- char mmcfilename[] = " ";
- char *dotpos;
-
- /////////// Attention please: /////////////////////
- // //
- // if other Alternate function apart from MMCI //
- // are selected, the MMCI I/F has some problems //
- // //
- ////////////////////////////////////////////////////
-
- gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
- // Power-on the controller
- response = mmc_enable ();
-
- if (response != MMC_OK)
- {
-
- response = mmc_enable (); // This actually IS necessary because it takes time for newly-inserted cards initialize. ~Chris S.
- if (response != MMC_OK)
- {
- printf ("Error in card power on\n");
- result = FAIL;
- goto end;
- }
- }
- // Initialise the cards on the bus, if any
- response = mmc_initCard ();
-
- if (response != MMC_OK)
- {
- printf ("Error in card initialization\n");
- result = FAIL;
- goto end;
- }
- // Get card info: CID, CSD, RCA registers
- response = mmc_readcsd (CSD);
-
- if (response != MMC_OK)
- {
- printf ("Error while fetching card info\n");
- result = FAIL;
- goto end;
- }
-
- // Select card and switch to 4-Bit, TODO HS if possible
- response = mmc_select_n_switch ();
-
- if (response != MMC_OK)
- {
- printf ("Error while select or switching to 4-bit/HS\n");
- goto end;
- }
-
- // Read the MBR
- response = mmc_readblock (1, 0, (u32 *) sector, 512, MMCPOLLING);
-
- if (response != MMC_OK)
- {
- printf ("Error while reading boot record\n");
- result = FAIL;
- goto end;
- }
- if (sector[446] == 0x00 || sector[446] == 0x80)
- { // found a MBR at the beginning of card
- BRStartSector = sector[454];
- }
- else
- { // BR at the beginning of card
- BRStartSector = 0x00;
- }
- // Read the BR
- response = mmc_readblock (1, (u32) (512 * BRStartSector), (u32 *) & mmc_boot_record, 512, MMCPOLLING);
-
- k = 0;
- while (response == MMC_DATA_CRC_FAIL && (k < 2))
- {
- response = mmc_readblock (1, (u32) (512 * BRStartSector), (u32 *) & mmc_boot_record, 512, MMCPOLLING);
- k++;
- }
- if (response != MMC_OK)
- {
- printf ("Error while reading boot record\n");
- result = FAIL;
- goto end;
- }
- mmc_copyByteH (mmc_boot_record.BytesPerSector, (u8 *) & BytesPerSector, 2);
- mmc_copyByteH (mmc_boot_record.ReservedSectors, (u8 *) & ReservedSectors, 2);
- FATStartSector = BRStartSector + ReservedSectors; // the field at offset 15 contains the number of reserved sectors at
- // the beginning of the media including the boot sector
- mmc_copyByteH (mmc_boot_record.SectorsPerFat, (u8 *) & SectorsPerFAT, 2);
- SectorsPerCluster = mmc_boot_record.SectorsPerCluster[0];
- mmc_copyByteH (mmc_boot_record.NumOfRootEntries, (u8 *) & MaxRDEntries, 2);
- FATStartSector += SectorsPerFAT;
- RDStartSector = FATStartSector + SectorsPerFAT;
- DataStartSector = RDStartSector + (u32) ((MaxRDEntries * 32) / 512);
-
-
-
- // convert filename into mmc compatible file name (upper case , <= 8+3 char, no dot, no extension)
- filelength = strlen (filename);
- dotpos = strchr (filename, '.');
- if (dotpos == NULL)
- {
- // no dot
- if (filelength <= 8)
- {
- for (j = 0; j < filelength; j++)
- {
- mmcfilename[j] = (char) toupper (filename[j]);
- }
- }
- else
- {
- for (j = 0; j < 6; j++)
- {
- mmcfilename[j] = (char) toupper (filename[j]);
- }
- mmcfilename[7] = '~';
- mmcfilename[8] = '1';
- filelength = 8;
- }
- }
- else
- {
- // dot
- if ((dotpos - filename) <= 8)
- {
- for (j = 0; j < (dotpos - filename); j++)
- {
- mmcfilename[j] = (char) toupper (filename[j]);
- }
- for (; j < 8; j++)
- {
- mmcfilename[j] = ' ';
- }
- // copy 3 char after .
- mmcfilename[j++] = (char) toupper (dotpos[1]);
- mmcfilename[j++] = (char) toupper (dotpos[2]);
- mmcfilename[j++] = (char) toupper (dotpos[3]);
-
- }
- else
- {
- for (j = 0; j < 6; j++)
- {
- mmcfilename[j] = (char) toupper (filename[j]);
- }
- mmcfilename[6] = '~';
- mmcfilename[7] = '1';
- // copy 3 char after .
- mmcfilename[8] = (char) toupper (dotpos[1]);
- mmcfilename[9] = (char) toupper (dotpos[2]);
- mmcfilename[10] = (char) toupper (dotpos[3]);
- }
- filelength = 11;
- }
- mmcfilename[11] = '\0';
-
-
- // search Root Directory for entry filename
- goout = 0;
- found = 0;
- for (j = 0; j < (DataStartSector - RDStartSector); j++)
- {
- if (goout == 1)
- break;
- response = mmc_readblock (1, (u32) ((RDStartSector + j) * 512), (u32 *) sector, 512, MMCPOLLING);
- if (response != MMC_OK)
- {
- printf ("Error while reading root directory\n");
- result = FAIL;
- goto end;
- }
-
- for (i = 0; i < 512; i += 32)
- {
- strncpy (nomefile, (char *) &sector[i], filelength);
- if (strcmp (nomefile, mmcfilename) == 0)
- {
- mmc_copyByteH (&sector[i + 26], (u8 *) & FileStartCluster, 2);
- mmc_copyByteH (&sector[i + 28], (u8 *) FileSize, 4);
- FileStartCluster -= 2;
- goout = 1;
- found = 1;
- break;
- }
- if (nomefile[0] == 0)
- { // end of Root Directory
- goout = 1;
- break;
- }
- }
- }
-
- // size of file : *FileSize ( 32 bits quantum)
- // number of bytes per sector : BytesPerSector
- // Beginning of file : FileStartSector
-
- printf ("Bytes per sector : %d \n", BytesPerSector );
- printf ("Sectors per cluster : %d \n", SectorsPerCluster );
- if (found)
- {
- u32 remaining = *FileSize ;
- u32 count;
- u32 burstsize = BytesPerSector ;
-
- FileStartSector = ( DataStartSector + (u32)(FileStartCluster * SectorsPerCluster)) ;
- printf ("Reading file %s from MMC ..., start sector = %d, address 0x%x \n",filename,FileStartSector,address);
- count = SectorsPerCluster - (FileStartSector % SectorsPerCluster) ;
- FileStartSector = FileStartSector * BytesPerSector; // the first burst might be different to align of clusters
-
- do
- {
- if ( remaining >= burstsize )
- { // read straight burst
-
- k = 0;
- do
- {
- response = mmc_readblock (1, (u32) FileStartSector , (u32 *) mem_address, burstsize , MMCPOLLING);
- k++;
-
- } while ((response==MMC_DATA_CRC_FAIL)&&(k<4));
- if ( k != 1) printf ("!");
- FileStartSector += burstsize;
- mem_address += burstsize;
- remaining -= burstsize;
- }
- else
- { // read burst +1 and perform memcpy
-
- burstsize = ((remaining + (BytesPerSector-1))/BytesPerSector) * BytesPerSector ;
- k = 0;
- do
- {
- response = mmc_readblock (1, (u32) FileStartSector , (u32 *) MMCBuffer , burstsize , MMCPOLLING);
- k++;
- } while ((response==MMC_DATA_CRC_FAIL)&&(k<4));
- if ( k != 1) printf ("!");
- memcpy ((char *) mem_address, (char *)MMCBuffer,remaining);
- remaining = 0;
- }
- if (response != MMC_OK)
- {
- printf ("Error while reading file %s\n", filename);
- result = FAIL;
- goto end;
- }
- } while ( remaining );
-
- }
- else
- {
- printf ("Unable to find %s on Multi Media Card\n", filename);
- response = MMC_INVALID_PARAMETER;
- result = FAIL;
- goto end;
- }
-
-end:
-
- return response;
-}
+U_BOOT_CMD(
+ write_partition_block, 1, 0, write_partition_block,
+ "- write partition block on emmc device\n",
+ NULL
+);
/*
* command line commands
*/
-
-static char mmc_cmdbuffer[1024] ;
-
-static int copy_file_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
#ifdef CONFIG_CMD_FAT
- unsigned long address;
- long sz;
-
- address = simple_strtoul (argv[2], 0, 16);
-
- printf("copy_file_mmc : filename = %s\n", argv[1]);
- printf("copy_file_mmc : address = %lx\n", address);
-
- sz = file_fat_read(argv[1], (void *)address, 0);
- if (sz == -1)
- {
- printf("copy_file_mmc error : in loading file \n");
- return 1;
- }
-
- return 0;
-#else
- unsigned long address;
- unsigned long filesize;
- int load_result = 1;
- unsigned long error_name = 0;
- char filename[30] ;
- {
- strcpy(filename , argv[1]);
- address = simple_strtoul (argv[2],0,16);//argv[2];
-
- printf("copy_file_mmc : filename = %s\n",filename);
- printf("copy_file_mmc : address = %lx\n",address);
-
- load_result = mmc_read_file(filename,address,&filesize);
- if (load_result != 0)
- {
- error_name = (unsigned long) (-load_result);
- printf("copy_file_mmc error : in loading file \n");
- }
- return(0);
- }
-#endif
-}
-
-static int mmc_read_cmd_file (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int mmc_read_cmd_file(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *argv[])
{
-#ifdef CONFIG_CMD_FAT
- long sz;
-
- sz = file_fat_read("command.txt", &mmc_cmdbuffer, sizeof(mmc_cmdbuffer) - 1);
- if (sz == -1)
- {
- printf("No command.txt found in the Card\n");
- return 1;
- }
-
- mmc_cmdbuffer[sz] = '\0';
- setenv ("bootcmd", mmc_cmdbuffer);
- return 0;
-#else
- unsigned long filesize;
- int load_result = 1;
- unsigned long error_name = 0;
-
- load_result = mmc_read_file("command.txt",(unsigned long)&mmc_cmdbuffer,&filesize);
- if (load_result != 0)
- {
- error_name = (unsigned long) (-load_result);
- printf("mmc_read_cmd_file error : in loading file \n");
- }
- else
- {
- setenv ("bootcmd", mmc_cmdbuffer);
- }
- return(0);
-#endif
+ long sz;
+ char mmc_cmdbuffer[1024];
+
+ sz = file_fat_read("command.txt", &mmc_cmdbuffer,
+ sizeof(mmc_cmdbuffer) - 1);
+ if (sz == -1) {
+ printf("No command.txt found in the MMC/SD card\n");
+ return 1;
+ }
+
+ mmc_cmdbuffer[sz] = '\0';
+ setenv("bootcmd", mmc_cmdbuffer);
+ return 0;
}
U_BOOT_CMD(
- copy_file_mmc, 3, 0, copy_file_mmc,
- "- copy file from mmc card\n",
- "filename address\n"
- " - load binary file from the MMC/SD card to a memory address\n"
-);
-
-
-U_BOOT_CMD(
- mmc_read_cmd_file, 1, 0, mmc_read_cmd_file,
- "- copy command file from mmc card\n",
+ mmc_read_cmd_file, 1, 0, mmc_read_cmd_file,
+ "- setup bootcmd env by reading command.txt file from MMC/SD card\n",
NULL
);
+#endif
/* ------------------------------- End of file ---------------------------- */
diff --git a/board/st/u8500/mmc_utils.h b/board/st/u8500/mmc_utils.h
deleted file mode 100755
index c0b997a5e..000000000
--- a/board/st/u8500/mmc_utils.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-#ifndef __MMC_UTILS_H
-#define __MMC_UTILS_H
-
-#include <common.h>
-
-typedef struct
-{
- u8 jump [3];
- u8 OEMname [8];
- u8 BytesPerSector [2];
- u8 SectorsPerCluster [1];
- u8 ReservedSectors [2];
- u8 NumOfFAT [1];
- u8 NumOfRootEntries [2];
- u8 NumOfSectors [2];
- u8 MediaDesc [1];
- u8 SectorsPerFat [2];
- u8 SectorsPerTrack [2];
- u8 NumOfHeads [2];
- u8 NumOfHiddenSectors [4];
- u8 NumOfTotSectors [4];
- u8 DriveNumber [1];
- u8 reserved [1];
- u8 ExtBootSig [1];
- u8 VolumeID [4];
- u8 VolumeLabel [11];
- u8 FSType [8];
- u8 LoadProg [448];
- u8 Signature [2];
-} t_mmc_boot_record;
-
-typedef struct
-{
- u8 filename [8];
- u8 extension [3];
- u8 attrib ;
- u8 reserved [10];
- u8 hour [2];
- u8 date [2];
- u8 startCluster [2];
- u8 dimension [4];
-} t_mmc_root_entry;
-
-typedef struct s_root_elem
-{
- char name[8];
- char ext[3];
- char nulll[0xf];
- short offset;
- unsigned sizee;
-} s_root_elem;
-
-typedef struct s_root
-{
- s_root_elem elem[16];
-} s_root;
-
-typedef struct s_file_elem
-{
- char filename [8] ;
-} s_file_elem;
-
-typedef struct s_file_list
-{
- s_file_elem elem [30];
-} s_file_list ;
-
-typedef enum
-{
- MMCPOLLING,
- MMCDMA
-}t_mmc_transfer_mode;
-
-
-t_mmc_error mmc_readblock (u8 cardno, u32 addr, u32* readbuff, u16 blocksize, t_mmc_transfer_mode transfer_mode);
-t_mmc_error mmc_writeblock (u8 cardno, u32 addr, u32* writebuff, u16 blocksize, t_mmc_transfer_mode transfer_mode);
-t_mmc_error mmc_enable (void);
-t_mmc_error mmc_disable (void);
-t_mmc_error mmc_initCard (void);
-t_mmc_error mmc_readcsd (u32 *response);
-t_mmc_error mmc_readcid (u32 *response) ;
-t_mmc_error display_file_list(char *extension);
-
-#endif /* !defined(__MMC_UTILS_H) */
-
-
diff --git a/board/st/u8500/u8500.c b/board/st/u8500/u8500.c
index 7c47ab977..eb6dda5af 100644
--- a/board/st/u8500/u8500.c
+++ b/board/st/u8500/u8500.c
@@ -420,7 +420,6 @@ static void init_regs(void)
}
} else {
struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
- u32 tmp;
/* Enable timers */
writel(1 << 17, &prcmu->tcr);
@@ -435,13 +434,6 @@ static void init_regs(void)
u8500_prcmu_enable(&prcmu->uartclk_mgt);
u8500_prcmu_enable(&prcmu->i2cclk_mgt);
- if (!u8500_is_earlydrop()) {
- /* Switch SDMMCCLK to 52Mhz instead of 104Mhz */
- tmp = readl(&prcmu->sdmmcclk_mgt);
- tmp = (tmp & ~0x1f) | 16;
- writel(tmp, &prcmu->sdmmcclk_mgt);
- }
-
u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
u8500_clock_enable(1, 9, -1); /* GPIO0 */