uboot/arch/arm/cpu/arm720t/lpc2292/mmc.c
<<
>>
Prefs
   1/*
   2 * This program is free software; you can redistribute it and/or
   3 * modify it under the terms of the GNU General Public License as
   4 * published by the Free Software Foundation; either version 2 of
   5 * the License, or (at your option) any later version.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 *
  12 * You should have received a copy of the GNU General Public License
  13 * along with this program; if not, write to the Free Software
  14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  15 * MA 02111-1307 USA
  16 */
  17
  18#include <config.h>
  19#include <common.h>
  20#include <mmc.h>
  21#include <asm/errno.h>
  22#include <asm/arch/hardware.h>
  23#include <part.h>
  24#include <fat.h>
  25#include "mmc_hw.h"
  26#include <asm/arch/spi.h>
  27
  28#ifdef CONFIG_MMC
  29
  30#undef MMC_DEBUG
  31
  32static block_dev_desc_t mmc_dev;
  33
  34/* these are filled out by a call to mmc_hw_get_parameters */
  35static int hw_size;             /* in kbytes */
  36static int hw_nr_sects;
  37static int hw_sect_size;        /* in bytes */
  38
  39block_dev_desc_t * mmc_get_dev(int dev)
  40{
  41        return (block_dev_desc_t *)(&mmc_dev);
  42}
  43
  44unsigned long mmc_block_read(int dev,
  45                             unsigned long start,
  46                             lbaint_t blkcnt,
  47                             void *buffer)
  48{
  49        unsigned long rc = 0;
  50        unsigned char *p = (unsigned char *)buffer;
  51        unsigned long i;
  52        unsigned long addr = start;
  53
  54#ifdef MMC_DEBUG
  55        printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start,
  56                 (unsigned long)blkcnt);
  57#endif
  58
  59        for(i = 0; i < (unsigned long)blkcnt; i++) {
  60#ifdef MMC_DEBUG
  61                printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p);
  62#endif
  63                (void)mmc_read_sector(addr, p);
  64                rc++;
  65                addr++;
  66                p += hw_sect_size;
  67        }
  68
  69        return rc;
  70}
  71
  72/*-----------------------------------------------------------------------------
  73 * Read hardware paramterers (sector size, size, number of sectors)
  74 */
  75static int mmc_hw_get_parameters(void)
  76{
  77        unsigned char csddata[16];
  78        unsigned int sizemult;
  79        unsigned int size;
  80
  81        mmc_read_csd(csddata);
  82        hw_sect_size = 1<<(csddata[5] & 0x0f);
  83        size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0);
  84        sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1);
  85        hw_nr_sects = (size+1)*(1<<(sizemult+2));
  86        hw_size = hw_nr_sects*hw_sect_size/1024;
  87
  88#ifdef MMC_DEBUG
  89        printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, "
  90                 "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size);
  91#endif
  92
  93        return 0;
  94}
  95
  96int mmc_legacy_init(int verbose)
  97{
  98        int ret = -ENODEV;
  99
 100        if (verbose)
 101                printf("mmc_legacy_init\n");
 102
 103        spi_init();
 104        /* this meeds to be done twice */
 105        mmc_hw_init();
 106        udelay(1000);
 107        mmc_hw_init();
 108
 109        mmc_hw_get_parameters();
 110
 111        mmc_dev.if_type = IF_TYPE_MMC;
 112        mmc_dev.part_type = PART_TYPE_DOS;
 113        mmc_dev.dev = 0;
 114        mmc_dev.lun = 0;
 115        mmc_dev.type = 0;
 116        mmc_dev.blksz = hw_sect_size;
 117        mmc_dev.lba = hw_nr_sects;
 118        sprintf((char*)mmc_dev.vendor, "Unknown vendor");
 119        sprintf((char*)mmc_dev.product, "Unknown product");
 120        sprintf((char*)mmc_dev.revision, "N/A");
 121        mmc_dev.removable = 0;  /* should be true??? */
 122        mmc_dev.block_read = mmc_block_read;
 123
 124        fat_register_device(&mmc_dev, 1);
 125
 126        ret = 0;
 127
 128        return ret;
 129}
 130
 131#endif /* CONFIG_MMC */
 132