[U-Boot] [PATCH v5] mmc: add generic mmc spi driver

Thomas Chou thomas at wytron.com.tw
Thu Apr 29 07:52:14 CEST 2010


Hi Andy,

Thanks for you review.

On 04/28/2010 11:21 PM, Andy Fleming wrote:
>
>> The crc7 lib func is merged from linux and used to compute mmc
>> command checksum.
>>      
> This should probably be a separate patch.
>
>    
OK.
>
>> +
>> +       do {
>> +               mmc = find_mmc_device(++dev_num);
>> +       } while (mmc&&  strcmp(mmc->name, "MMC_SPI"));
>> +       if (!mmc) {
>> +               printf("Create MMC Device\n");
>> +               mmc = mmc_spi_init(CONFIG_MMC_SPI_BUS,
>> +                                  CONFIG_MMC_SPI_CS,
>> +                                  CONFIG_MMC_SPI_SPEED,
>> +                                  CONFIG_MMC_SPI_MODE);
>> +               if (!mmc) {
>> +                       printf("Failed to create MMC Device\n");
>> +                       return 1;
>> +               }
>> +               dev_num = mmc->block_dev.dev;
>> +       }
>>      
> I'm not sure I understand the logic behind this code.  The arguments
> to the command should be used to either find the already-existing bus,
> or to create a new one.  Unless I'm misunderstanding, this searches
> for the first MMC_SPI bus, and if it finds it, uses that, otherwise it
> creates a new one with the values specified in the config file.  Then
> it parses the command and overwrites the old parameters for the bus
> with new ones?  Why?  My instinct would be to create a separate
> instance of an MMC_SPI bus for each bus and chip select.  My SPI is
> rusty, so maybe chip-select should be configurable on a use-by-use
> basis.
>
> Certainly the current code will only use at most one MMC_SPI bus even
> if more are created, which seems wrong.
>    
Though more than one MMC_SPI device can be created for specific bus and 
cs by calling mmc_spi_init() within board_mmc_init() or cpu_mmc_init(). 
This command is used to change the spi bus and chip select on a 
use-by-use basis at run time, so one changeable mmc_spi device (the 
first one if we found) should be enough.


>
>> +       cmdo[1] = 0x40 + cmdidx;
>>      
> Use a #define'd constant for 0x40.  Maybe do this:
>
> /* MMC SPI commands start with a start bit "0" and a transmit bit "1" */
> #define MMC_SPI_CMD(x) (0x40 | (x&  0x3f))
>
> cmdo[1] = MMC_SPI_CMD(cmdidx);
>    
OK. Will define macros for all the cmd, token and response.

> Why not check the CRC to make sure your data is correct?
>    
OK. Will check CRC on data packet.


>> +
>> +static inline uint rswab(u8 *d)
>>      
> Did you mean "swap", here?
>    
It should be swap.

> Hmmm....  I'm not entirely sure this is the way to go.  If I'm reading
> this correctly, this function is converting between the standard SD
> protocol, and the SPI version of the protocol.  It might be better to
> make mmc.c aware of which protocol it is using, so it a) doesn't issue
> commands that the SPI card doesn't understand, and b) can properly
> interpret responses.
>
>    
I have avoided to touch the core mmc.c, so that I won't break other SD 
hosts by accident. Only minor translation of initialization commands and 
status mapping is enough to support SPI protocol.
>    
>> +       }
>> +       if (data) {
>> +               debug("%s:data %x %x %x\n", __func__,
>> +                     data->flags, data->blocks, data->blocksize);
>> +               if (data->flags == MMC_DATA_READ) {
>> +                       r1 = mmc_spi_readdata(mmc, data->dest,
>> +                                       data->blocks, data->blocksize);
>> +               } else if  (data->flags == MMC_DATA_WRITE) {
>> +                       if (cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)
>> +                               r1 = mmc_spi_writeblock(mmc, data->src,
>> +                                       data->blocks, data->blocksize);
>> +                       else
>> +                               r1 = mmc_spi_writedata(mmc, data->src,
>> +                                       data->blocks, data->blocksize);
>> +               }
>>      
> Why not check r1 to make sure your writes actually succeeded?
>
>    
OK. Will check data response.
>    
>> +
>> +       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
>>      
> Is this part of the SPI spec?  If so, this is fine, otherwise, we need
> to get the voltage information from the SPI bus, somehow.
>
>    
There is no voltage capability from SPI bus. This assumes 3.3V 
interface. Should I include other voltage?

>    
>> +       mmc->f_max = speed;
>> +       mmc->f_min = mmc->f_max>>  9;
>>      
> What's the logic behind f_min being f_max/512?
>
>    
It yields f_min lower than 400KHz to meet the requirement for MMC.

Best regards,
Thomas


More information about the U-Boot mailing list