diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2010-07-02 13:47:39 +0200 |
---|---|---|
committer | Michael BRANDT <michael.brandt@stericsson.com> | 2010-08-11 10:53:36 +0200 |
commit | 33a2e90bf491f13a4546d09a6105582c0ba7f313 (patch) | |
tree | b986e40cefe66056013a73977976b1fa38b334c4 /board/st/u8500/emmc.c | |
parent | 415211fa4c850467b3e45b7cdb2405ac018dec77 (diff) |
Replace MMC/SD driver to fit new framework.
IR265772: MMC driver does not detect SDHC cards.
IR254201: Restructure MMC/SD driver for U8500 board according to the
block device framework in mainline U-Boot.
Changes to mmc framework:
- Multi Block Read support in mmc framework.
- Wrap Multi Block Write/Read to be able to adopt for large transaction.
- Removed incorrect check in EXT CSD for high capacity MMC.
- Corrected check for high capacity SD cards.
- Set MMC buswidth to 8, prio of using 4.
Known limitations/bugs in mmc framework:
- High capacity MMC, will likely not get the correct density.
- High speed is set, whether or not the host supports it or not.
board/st/u8500/mmc_utils:
IMPORTANT FOR DEVELOPERS:
- Removed unessary U-Boot commands which is already supported in
cmd_fat.
- mmc_read_cmd_file: Read command.txt into bootcmd env from FAT FS in
SD card.
- write_partition_block: Writes the MBR if it is not already written.
board/st/u8500/mmc_host[c.h]:
- Implements the entire MMC/SD host driver for the PL180 block.
- There is still room for optimization:
Increase CLK-speed.
Use high-speed for SD cards.
Is GPIO setup correctly for both cards an eMMC.
EarlyDrop support not fully tested.
Dynamically turn on voltage/clocks to SD, not always.
More...
Note:
- Increased read/write performance for eMMC, to around 5.4 MB/s for
sequential read/write. Earlier measurements was 3.5 MB/s for read and
2.6 MB/s for write.
ST-Ericsson ID: ER265772, CR267996, ER267993
Change-Id: I921102edbde761407ff5ad476d1bb99f5dc7a2ef
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/2288
Reviewed-by: Michael BRANDT <michael.brandt@stericsson.com>
Tested-by: Michael BRANDT <michael.brandt@stericsson.com>
Reviewed-by: Martin LUNDHOLM <martin.xa.lundholm@stericsson.com>
Tested-by: Martin LUNDHOLM <martin.xa.lundholm@stericsson.com>
Reviewed-by: Mikael LARSSON <mikael.xt.larsson@stericsson.com>
Tested-by: Mikael LARSSON <mikael.xt.larsson@stericsson.com>
Diffstat (limited to 'board/st/u8500/emmc.c')
-rw-r--r-- | board/st/u8500/emmc.c | 391 |
1 files changed, 0 insertions, 391 deletions
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 ---------------------------- */ |