SD/MMC with db1100

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello all,

I'm now tring SD subsystem on Au1100 with Syrah Rev 1.

Before porting handhelds.org's mmc driver, I just tried the attached
code, but it doesn't seems to work.

SD controler seems to emit right command to sd card, but there is no
response from sd card and timeouts.

Could someone enlighten me what's wrong with my code? or does anyone
successfully used sd/mmc on au1?

tia,
--
         yashi (leaving to Canada in a few hours...)



#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>

#include <asm/au1000.h>

MODULE_LICENSE("GPL");

int sd_init(void)
{
        u32 cpupll, sd;

        au_writel(0xffffffff, 0xb0600018); /* clear all status */

        /* just checking */
        cpupll = au_readl(0xb1900060) & 0x3f;
        sd = (au_readl(0xb190003c) & 0x3) + 2;
        printk("CPU PLL %d => CPU freq %dMHz\n", cpupll, 12 * cpupll);
        printk("System Bus clock Div %d => System Bus %dMHz\n",
               sd, 12 * cpupll / sd);
        printk("Peripheral clock is %dkHz\n",
               (12 * 1000) * cpupll / sd / 2);

        /* SD Enable Register */
        au_writel(0x1, 0xb060000c);      /* periperal rest: R */
        au_writel(0x3, 0xb060000c);      /* periperal reset and clock enable: R | CE */

        mdelay(1);

        /* SD Config Register */
        au_writel(0x3ff, 0xb0600008);    /* set slowest clock */

        printk("SD Clock is %dHz\n", (12 * 1000 * 1000) * cpupll / sd / 2 / (2*((0x1ff)+1)));

        /* SD Config Register 2*/
        au_writel(0x2, 0xb0600010);      /* FF(Force FIFO flush and reset) */
        au_writel(0x0, 0xb0600010);      /* clear FF */
        au_writel(0x1, 0xb0600010);      /* Enable serial interface state machine */

        /* SD Timeout Register */
        au_writel(0x1fffff, 0xb0600038); /* max timeout */

        /* CMD0 */
        au_writel(0x0, 0xb0600024);
        au_writel(0x1, 0xb0600020);

        while (!(au_readl(0xb0600018) & 0x10000))
                ;

        printk("Status Register %#x\n", au_readl(0xb0600018));
        au_writel(0x10000, 0xb0600018);
        printk("Status Register %#x\n", au_readl(0xb0600018));

        /* CMD1 */
        au_writel(0x0, 0xb0600024);
        au_writel(0x30101, 0xb0600020);  /* R3 | CMD1 | CT 0 | GO */
//        au_writel(0x0, 0xb0600024); /* ocr */
//        au_writel(0x32901, 0xb0600020);  /* R3 | CMD1 | CT 0 | GO */

        while (!(au_readl(0xb0600018) & 0x10000) &&
               !(au_readl(0xb0600018) & 0x20000))
                ;

        printk("Status Register %#x\n", au_readl(0xb0600018));

        printk("Response Register 0 %#x\n", au_readl(0xb0600034));
        printk("Response Register 1 %#x\n", au_readl(0xb0600030));
        printk("Response Register 2 %#x\n", au_readl(0xb060002c));
        printk("Response Register 3 %#x\n", au_readl(0xb0600028));

        mdelay(100);
        printk("Status Register %#x\n", au_readl(0xb0600018));

        return -1; /* too lazy to rmmod */
}

void sd_cleanup(void)
{
}

module_init(sd_init);
module_exit(sd_cleanup);


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux