mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
Embryo of a SD driver for Sansav2
Debug code included, needed until the bootloader is ready git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18926 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
4c457afe89
commit
e1b4838481
4 changed files with 469 additions and 1 deletions
|
|
@ -30,6 +30,7 @@
|
||||||
#include "backlight-target.h"
|
#include "backlight-target.h"
|
||||||
#include "as3525-codec.h"
|
#include "as3525-codec.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "ata.h"
|
||||||
|
|
||||||
int show_logo(void);
|
int show_logo(void);
|
||||||
void main(void)
|
void main(void)
|
||||||
|
|
@ -52,7 +53,9 @@ void main(void)
|
||||||
buf[i] = as3525_codec_read(0x38 + i);
|
buf[i] = as3525_codec_read(0x38 + i);
|
||||||
}
|
}
|
||||||
printf("ID: %02X%02X%02X%02X%02X%02X%02X%02X", buf[7], buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
|
printf("ID: %02X%02X%02X%02X%02X%02X%02X%02X", buf[7], buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
|
||||||
|
|
||||||
|
ata_init();
|
||||||
|
|
||||||
#ifdef SANSA_CLIP
|
#ifdef SANSA_CLIP
|
||||||
/* Use hardware scrolling */
|
/* Use hardware scrolling */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,7 @@ target/arm/pnx0101/system-pnx0101.c
|
||||||
|
|
||||||
#if CONFIG_CPU == AS3525
|
#if CONFIG_CPU == AS3525
|
||||||
target/arm/as3525/system-as3525.c
|
target/arm/as3525/system-as3525.c
|
||||||
|
target/arm/as3525/ata_sd_as3525.c
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CPU_PP)
|
#if defined(CPU_PP)
|
||||||
|
|
|
||||||
341
firmware/target/arm/as3525/ata_sd_as3525.c
Normal file
341
firmware/target/arm/as3525/ata_sd_as3525.c
Normal file
|
|
@ -0,0 +1,341 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright © 2008 Rafaël Carré
|
||||||
|
*
|
||||||
|
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Driver for the ARM PL180 SD/MMC controller inside AS3525 SoC */
|
||||||
|
|
||||||
|
#include "config.h" /* for HAVE_MULTIVOLUME */
|
||||||
|
|
||||||
|
#include "as3525.h"
|
||||||
|
#include "mmci.h"
|
||||||
|
#include "panic.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include "ata.h"
|
||||||
|
|
||||||
|
#define NAND_AS3525 0
|
||||||
|
#define SD_AS3525 1
|
||||||
|
static int pl180_base[2] = { NAND_FLASH_BASE, SD_MCI_BASE };
|
||||||
|
|
||||||
|
/* ARM PL180 registers */
|
||||||
|
#define MMC_POWER(i) (*(volatile unsigned long *) (pl180_base[i]+0x00))
|
||||||
|
#define MMC_CLOCK(i) (*(volatile unsigned long *) (pl180_base[i]+0x04))
|
||||||
|
#define MMC_ARGUMENT(i) (*(volatile unsigned long *) (pl180_base[i]+0x08))
|
||||||
|
#define MMC_COMMAND(i) (*(volatile unsigned long *) (pl180_base[i]+0x0C))
|
||||||
|
#define MMC_RESPCMD(i) (*(volatile unsigned long *) (pl180_base[i]+0x10))
|
||||||
|
#define MMC_RESP0(i) (*(volatile unsigned long *) (pl180_base[i]+0x14))
|
||||||
|
#define MMC_RESP1(i) (*(volatile unsigned long *) (pl180_base[i]+0x18))
|
||||||
|
#define MMC_RESP2(i) (*(volatile unsigned long *) (pl180_base[i]+0x1C))
|
||||||
|
#define MMC_RESP3(i) (*(volatile unsigned long *) (pl180_base[i]+0x20))
|
||||||
|
#define MMC_DATACTRL(i) (*(volatile unsigned long *) (pl180_base[i]+0x2C))
|
||||||
|
#define MMC_STATUS(i) (*(volatile unsigned long *) (pl180_base[i]+0x34))
|
||||||
|
#define MMC_CLEAR(i) (*(volatile unsigned long *) (pl180_base[i]+0x38))
|
||||||
|
#define MMC_MASK0(i) (*(volatile unsigned long *) (pl180_base[i]+0x3C))
|
||||||
|
#define MMC_MASK1(i) (*(volatile unsigned long *) (pl180_base[i]+0x40))
|
||||||
|
#define MMC_SELECT(i) (*(volatile unsigned long *) (pl180_base[i]+0x44))
|
||||||
|
|
||||||
|
|
||||||
|
/* SD commands */
|
||||||
|
#define GO_IDLE_STATE 0
|
||||||
|
#define MMC_CMD_READ_CID 2
|
||||||
|
#define SEND_IF_COND 8
|
||||||
|
#define SEND_OP_COND 41
|
||||||
|
#define APP_CMD 55
|
||||||
|
|
||||||
|
/* command flags */
|
||||||
|
#define MMC_NO_FLAGS (0<<0)
|
||||||
|
#define MMC_RESP (1<<0)
|
||||||
|
#define MMC_LONG_RESP (1<<1)
|
||||||
|
#define MMC_ARG (1<<2)
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
#define DEBUG
|
||||||
|
void reset_screen(void);
|
||||||
|
void printf(const char *format, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mmc_command
|
||||||
|
{
|
||||||
|
int cmd;
|
||||||
|
int arg;
|
||||||
|
int resp[4];
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void mci_delay(void) { int i = 0xffff; while(i--) ; }
|
||||||
|
|
||||||
|
static void mci_set_clock_divider(const int drive, int divider)
|
||||||
|
{
|
||||||
|
int clock = MMC_CLOCK(drive);
|
||||||
|
|
||||||
|
if(divider > 1)
|
||||||
|
{
|
||||||
|
/* use divide logic */
|
||||||
|
clock &= ~MCI_CLK_BYPASS;
|
||||||
|
|
||||||
|
/* convert divider to MMC_CLOCK logic */
|
||||||
|
divider = (divider/2) - 1;
|
||||||
|
if(divider >= 256)
|
||||||
|
divider = 255;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* bypass dividing logic */
|
||||||
|
clock |= MCI_CLK_BYPASS;
|
||||||
|
divider = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMC_CLOCK(drive) = clock | divider;
|
||||||
|
|
||||||
|
mci_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_cmd(const int drive, struct mmc_command *cmd)
|
||||||
|
{
|
||||||
|
int val, status;
|
||||||
|
|
||||||
|
while(MMC_STATUS(drive) & MCI_CMDACTIVE); /* useless */
|
||||||
|
|
||||||
|
if(MMC_COMMAND(drive) & MCI_CPSM_ENABLE) /* clears existing command */
|
||||||
|
{
|
||||||
|
MMC_COMMAND(drive) = 0;
|
||||||
|
mci_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
val = cmd->cmd | MCI_CPSM_ENABLE;
|
||||||
|
if(cmd->flags & MMC_RESP)
|
||||||
|
{
|
||||||
|
val |= MCI_CPSM_RESPONSE;
|
||||||
|
if(cmd->flags & MMC_LONG_RESP)
|
||||||
|
val |= MCI_CPSM_LONGRSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMC_CLEAR(drive) = 0x7ff;
|
||||||
|
|
||||||
|
MMC_ARGUMENT(drive) = (cmd->flags & MMC_ARG) ? cmd->arg : 0;
|
||||||
|
MMC_COMMAND(drive) = val;
|
||||||
|
|
||||||
|
while(MMC_STATUS(drive) & MCI_CMDACTIVE);
|
||||||
|
|
||||||
|
MMC_COMMAND(drive) = 0;
|
||||||
|
MMC_ARGUMENT(drive) = ~0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
status = MMC_STATUS(drive);
|
||||||
|
if(cmd->flags & MMC_RESP)
|
||||||
|
{
|
||||||
|
if(status & MCI_CMDTIMEOUT)
|
||||||
|
{
|
||||||
|
if(cmd->cmd == SEND_IF_COND)
|
||||||
|
break; /* SDHC test can fail */
|
||||||
|
panicf("Response timeout");
|
||||||
|
}
|
||||||
|
else if(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND))
|
||||||
|
{ /* resp received */
|
||||||
|
cmd->resp[0] = MMC_RESP0(drive);
|
||||||
|
if(cmd->flags & MMC_LONG_RESP)
|
||||||
|
{
|
||||||
|
cmd->resp[1] = MMC_RESP1(drive);
|
||||||
|
cmd->resp[2] = MMC_RESP2(drive);
|
||||||
|
cmd->resp[3] = MMC_RESP3(drive);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(status & MCI_CMDSENT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
} while(1);
|
||||||
|
|
||||||
|
MMC_CLEAR(drive) = 0x7ff;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sd_init_card(const int drive)
|
||||||
|
{
|
||||||
|
struct mmc_command cmd_app, cmd_op_cond, cmd_idle, cmd_if_cond;
|
||||||
|
int status;
|
||||||
|
bool sdhc;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
reset_screen();
|
||||||
|
printf("now - powered up");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cmd_idle.cmd = GO_IDLE_STATE;
|
||||||
|
cmd_idle.arg = 0;
|
||||||
|
cmd_idle.flags = MMC_NO_FLAGS;
|
||||||
|
if(send_cmd(drive, &cmd_idle) != MCI_CMDSENT)
|
||||||
|
panicf("goto idle failed!");
|
||||||
|
#ifdef DEBUG
|
||||||
|
else
|
||||||
|
printf("now - idle");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mci_delay();
|
||||||
|
|
||||||
|
cmd_if_cond.cmd = SEND_IF_COND;
|
||||||
|
cmd_if_cond.arg = (1 /* 2.7-3.6V */ << 8) | 0xAA /* check pattern */;
|
||||||
|
cmd_if_cond.flags = MMC_RESP | MMC_ARG;
|
||||||
|
|
||||||
|
cmd_app.cmd = APP_CMD;
|
||||||
|
cmd_app.flags = MMC_RESP | MMC_ARG;
|
||||||
|
cmd_app.arg = 0; /* 31:16 RCA (0) , 15:0 stuff bits */
|
||||||
|
|
||||||
|
cmd_op_cond.cmd = SEND_OP_COND;
|
||||||
|
cmd_op_cond.flags = MMC_RESP | MMC_ARG;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("now - card powering up");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sdhc = false;
|
||||||
|
status = send_cmd(drive, &cmd_if_cond);
|
||||||
|
if(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND))
|
||||||
|
{
|
||||||
|
if((cmd_if_cond.resp[0] & 0xFFF) == cmd_if_cond.arg)
|
||||||
|
sdhc = true;
|
||||||
|
#ifdef DEBUG
|
||||||
|
else
|
||||||
|
printf("Bad resp: %x",cmd_if_cond.arg);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
else
|
||||||
|
printf("cmd_if_cond stat: 0x%x",status);
|
||||||
|
|
||||||
|
printf("%s Capacity",sdhc?"High":"Normal");
|
||||||
|
mci_delay();
|
||||||
|
mci_delay();
|
||||||
|
mci_delay();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
int loop = 0;
|
||||||
|
#endif
|
||||||
|
do {
|
||||||
|
mci_delay();
|
||||||
|
mci_delay();
|
||||||
|
#ifdef DEBUG
|
||||||
|
reset_screen();
|
||||||
|
printf("Loop number #%d", ++loop);
|
||||||
|
#endif
|
||||||
|
/* app_cmd */
|
||||||
|
status = send_cmd(drive, &cmd_app);
|
||||||
|
if( !(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) ||
|
||||||
|
!(cmd_app.resp[0] & (1<<5)) )
|
||||||
|
{
|
||||||
|
panicf("app_cmd failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_op_cond.arg = sdhc ? 0x40FF8000 : (8<<0x14); /* ocr */
|
||||||
|
status = send_cmd(drive, &cmd_op_cond);
|
||||||
|
if(!(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)))
|
||||||
|
panicf("cmd_op_cond failed");
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("OP COND: 0x%.8x", cmd_op_cond.resp[0]);
|
||||||
|
#endif
|
||||||
|
} while(!(cmd_op_cond.resp[0] & (1<<31))); /* until card is powered up */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("now - card ready !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_pl180_controller(const int drive)
|
||||||
|
{
|
||||||
|
MMC_COMMAND(drive) = MMC_DATACTRL(drive) = 0;
|
||||||
|
MMC_CLEAR(drive) = 0x7ff;
|
||||||
|
|
||||||
|
MMC_MASK0(drive) = MMC_MASK1(drive) = 0; /* disable all interrupts */
|
||||||
|
|
||||||
|
MMC_POWER(drive) = MCI_PWR_UP | (10 /*voltage*/ << 2); /* use OF voltage */
|
||||||
|
mci_delay();
|
||||||
|
|
||||||
|
MMC_POWER(drive) |= MCI_PWR_ON;
|
||||||
|
mci_delay();
|
||||||
|
|
||||||
|
MMC_SELECT(drive) = 0;
|
||||||
|
|
||||||
|
MMC_CLOCK(drive) = MCI_CLK_ENABLE;
|
||||||
|
MMC_CLOCK(drive) &= ~MCI_CLK_PWRSAVE;
|
||||||
|
|
||||||
|
/* set MCLK divider */
|
||||||
|
mci_set_clock_divider(drive, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ata_init(void)
|
||||||
|
{
|
||||||
|
/* reset peripherals */
|
||||||
|
|
||||||
|
CCU_SRC =
|
||||||
|
#ifdef HAVE_MULTIVOLUME
|
||||||
|
CCU_SRC_SDMCI_EN |
|
||||||
|
#endif
|
||||||
|
CCU_SRC_NAF_EN | CCU_SRC_IDE_EN | CCU_SRC_IDE_AHB_EN | CCU_SRC_MST_EN;
|
||||||
|
|
||||||
|
CCU_SRL = CCU_SRL_MAGIC_NUMBER;
|
||||||
|
CCU_SRL = 0;
|
||||||
|
|
||||||
|
GPIOC_DIR &= ~(1<<1);
|
||||||
|
if(GPIOC_PIN(1))
|
||||||
|
CCU_SPARE1 |= 4; /* sets bit 3 of undocumented register */
|
||||||
|
else
|
||||||
|
CCU_SPARE1 &= ~4; /* or clear it */
|
||||||
|
|
||||||
|
CGU_IDE = (1<<7)|(1<<6); /* enable, 24MHz clock */
|
||||||
|
CGU_MEMSTICK = (1<<8); /* enable, 24MHz clock */
|
||||||
|
|
||||||
|
CGU_PERI |= CGU_NAF_CLOCK_ENABLE;
|
||||||
|
#ifdef HAVE_MULTIVOLUME
|
||||||
|
CGU_PERI |= CGU_MCI_CLOCK_ENABLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CCU_IO &= ~8; /* bits 3:2 = 01, xpd is SD interface */
|
||||||
|
CCU_IO |= 4;
|
||||||
|
|
||||||
|
init_pl180_controller(NAND_AS3525);
|
||||||
|
sd_init_card(NAND_AS3525);
|
||||||
|
|
||||||
|
#ifdef HAVE_MULTIVOLUME
|
||||||
|
init_pl180_controller(SD_AS3525);
|
||||||
|
sd_init_card(SD_AS3525);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf)
|
||||||
|
{
|
||||||
|
(void)start;
|
||||||
|
(void)count;
|
||||||
|
(void)buf;
|
||||||
|
return 0; /* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf)
|
||||||
|
{
|
||||||
|
(void)start;
|
||||||
|
(void)count;
|
||||||
|
(void)buf;
|
||||||
|
return 0; /* TODO */
|
||||||
|
}
|
||||||
123
firmware/target/arm/as3525/mmci.h
Normal file
123
firmware/target/arm/as3525/mmci.h
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* linux/drivers/mmc/host/mmci.h - ARM PrimeCell MMCI PL180/1 driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
//#define MMCIPOWER 0x000
|
||||||
|
#define MCI_PWR_OFF 0x00
|
||||||
|
#define MCI_PWR_UP 0x02
|
||||||
|
#define MCI_PWR_ON 0x03
|
||||||
|
#define MCI_OD (1 << 6)
|
||||||
|
#define MCI_ROD (1 << 7)
|
||||||
|
|
||||||
|
//#define MMCICLOCK 0x004
|
||||||
|
#define MCI_CLK_ENABLE (1 << 8)
|
||||||
|
#define MCI_CLK_PWRSAVE (1 << 9)
|
||||||
|
#define MCI_CLK_BYPASS (1 << 10)
|
||||||
|
#define MCI_WIDEBUS (1 << 11)
|
||||||
|
|
||||||
|
//#define MMCIARGUMENT 0x008
|
||||||
|
//#define MMCICOMMAND 0x00c
|
||||||
|
#define MCI_CPSM_RESPONSE (1 << 6)
|
||||||
|
#define MCI_CPSM_LONGRSP (1 << 7)
|
||||||
|
#define MCI_CPSM_INTERRUPT (1 << 8)
|
||||||
|
#define MCI_CPSM_PENDING (1 << 9)
|
||||||
|
#define MCI_CPSM_ENABLE (1 << 10)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define MMCIRESPCMD 0x010
|
||||||
|
#define MMCIRESPONSE0 0x014
|
||||||
|
#define MMCIRESPONSE1 0x018
|
||||||
|
#define MMCIRESPONSE2 0x01c
|
||||||
|
#define MMCIRESPONSE3 0x020
|
||||||
|
#define MMCIDATATIMER 0x024
|
||||||
|
#define MMCIDATALENGTH 0x028
|
||||||
|
#define MMCIDATACTRL 0x02c
|
||||||
|
#endif
|
||||||
|
#define MCI_DPSM_ENABLE (1 << 0)
|
||||||
|
#define MCI_DPSM_DIRECTION (1 << 1)
|
||||||
|
#define MCI_DPSM_MODE (1 << 2)
|
||||||
|
#define MCI_DPSM_DMAENABLE (1 << 3)
|
||||||
|
|
||||||
|
//#define MMCIDATACNT 0x030
|
||||||
|
//#define MMCISTATUS 0x034
|
||||||
|
#define MCI_CMDCRCFAIL (1 << 0)
|
||||||
|
#define MCI_DATACRCFAIL (1 << 1)
|
||||||
|
#define MCI_CMDTIMEOUT (1 << 2)
|
||||||
|
#define MCI_DATATIMEOUT (1 << 3)
|
||||||
|
#define MCI_TXUNDERRUN (1 << 4)
|
||||||
|
#define MCI_RXOVERRUN (1 << 5)
|
||||||
|
#define MCI_CMDRESPEND (1 << 6)
|
||||||
|
#define MCI_CMDSENT (1 << 7)
|
||||||
|
#define MCI_DATAEND (1 << 8)
|
||||||
|
#define MCI_DATABLOCKEND (1 << 10)
|
||||||
|
#define MCI_CMDACTIVE (1 << 11)
|
||||||
|
#define MCI_TXACTIVE (1 << 12)
|
||||||
|
#define MCI_RXACTIVE (1 << 13)
|
||||||
|
#define MCI_TXFIFOHALFEMPTY (1 << 14)
|
||||||
|
#define MCI_RXFIFOHALFFULL (1 << 15)
|
||||||
|
#define MCI_TXFIFOFULL (1 << 16)
|
||||||
|
#define MCI_RXFIFOFULL (1 << 17)
|
||||||
|
#define MCI_TXFIFOEMPTY (1 << 18)
|
||||||
|
#define MCI_RXFIFOEMPTY (1 << 19)
|
||||||
|
#define MCI_TXDATAAVLBL (1 << 20)
|
||||||
|
#define MCI_RXDATAAVLBL (1 << 21)
|
||||||
|
|
||||||
|
//#define MMCICLEAR 0x038
|
||||||
|
#define MCI_CMDCRCFAILCLR (1 << 0)
|
||||||
|
#define MCI_DATACRCFAILCLR (1 << 1)
|
||||||
|
#define MCI_CMDTIMEOUTCLR (1 << 2)
|
||||||
|
#define MCI_DATATIMEOUTCLR (1 << 3)
|
||||||
|
#define MCI_TXUNDERRUNCLR (1 << 4)
|
||||||
|
#define MCI_RXOVERRUNCLR (1 << 5)
|
||||||
|
#define MCI_CMDRESPENDCLR (1 << 6)
|
||||||
|
#define MCI_CMDSENTCLR (1 << 7)
|
||||||
|
#define MCI_DATAENDCLR (1 << 8)
|
||||||
|
#define MCI_DATABLOCKENDCLR (1 << 10)
|
||||||
|
|
||||||
|
//#define MMCIMASK0 0x03c
|
||||||
|
#define MCI_CMDCRCFAILMASK (1 << 0)
|
||||||
|
#define MCI_DATACRCFAILMASK (1 << 1)
|
||||||
|
#define MCI_CMDTIMEOUTMASK (1 << 2)
|
||||||
|
#define MCI_DATATIMEOUTMASK (1 << 3)
|
||||||
|
#define MCI_TXUNDERRUNMASK (1 << 4)
|
||||||
|
#define MCI_RXOVERRUNMASK (1 << 5)
|
||||||
|
#define MCI_CMDRESPENDMASK (1 << 6)
|
||||||
|
#define MCI_CMDSENTMASK (1 << 7)
|
||||||
|
#define MCI_DATAENDMASK (1 << 8)
|
||||||
|
#define MCI_DATABLOCKENDMASK (1 << 10)
|
||||||
|
#define MCI_CMDACTIVEMASK (1 << 11)
|
||||||
|
#define MCI_TXACTIVEMASK (1 << 12)
|
||||||
|
#define MCI_RXACTIVEMASK (1 << 13)
|
||||||
|
#define MCI_TXFIFOHALFEMPTYMASK (1 << 14)
|
||||||
|
#define MCI_RXFIFOHALFFULLMASK (1 << 15)
|
||||||
|
#define MCI_TXFIFOFULLMASK (1 << 16)
|
||||||
|
#define MCI_RXFIFOFULLMASK (1 << 17)
|
||||||
|
#define MCI_TXFIFOEMPTYMASK (1 << 18)
|
||||||
|
#define MCI_RXFIFOEMPTYMASK (1 << 19)
|
||||||
|
#define MCI_TXDATAAVLBLMASK (1 << 20)
|
||||||
|
#define MCI_RXDATAAVLBLMASK (1 << 21)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define MMCIMASK1 0x040
|
||||||
|
#define MMCIFIFOCNT 0x048
|
||||||
|
#define MMCIFIFO 0x080 /* to 0x0bc */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MCI_IRQENABLE \
|
||||||
|
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
|
||||||
|
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
|
||||||
|
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The size of the FIFO in bytes.
|
||||||
|
*/
|
||||||
|
#define MCI_FIFOSIZE (16*4)
|
||||||
|
|
||||||
|
#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
|
||||||
|
|
||||||
|
#define NR_SG 16
|
||||||
Loading…
Add table
Add a link
Reference in a new issue