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);
|