Tuesday, September 28, 2010

Bare Metal: PuppyBeagle interrupt controller (INTC) init file [mmc.c/mmc.h]

#include "sprint.h"
#include "prcm.h"
#include "mmc.h"
#include "i2c.h"
#include

//TWL MMC VOLT. ENABLE REG PHY. ADDRESS
#define VMMC1_DEDICATED 0x85

//PBIAS CONTROL REG PHY. ADDRESS
#define CM_CNTL_PBIAS_LITE 0x48002520

#define TWL_MMC3V 0x2
#define PBIASLITE_PWRDNZ0 1 << 1

void mmc_init (void)
{
int wait;
mmc_reg *pmmc = (mmc_reg *) MMC_REG_BASE;
corecm_reg *pcorecm = (corecm_reg *) CORECM_REG_BASE;
unsigned int *pcm = (unsigned int*) CM_CNTL_PBIAS_LITE;

//Config. PBIAS Voltage and internal clock
  i2c_reg_write(I2C1_TWLED_SLAVE_ADDR, VMMC1_DEDICATED, TWL_MMC3V);

/*Enable I & F Clocks for MMC module */
pcorecm->CORECM_FCLKEN1 |= MMC_CLOCK_EN;
pcorecm->CORECM_ICLKEN1 |= MMC_CLOCK_EN;

//VDDS MMC1 Stable
*pcm |= PBIASLITE_PWRDNZ0;

/*Do a soft reset of MMC module and wait for status done*/
pmmc->MMC_SYSCONFIG |= MMC_SW_RESET;
while (!(pmmc->MMC_SYSSTATUS |= MMC_RESET_DONE))
;

sprint ("Done with MMC RESET, WILL INIT. APPROPRIATE VOLTAGE...\n");

/*Initialize appropriate voltage sources to MMC*/
pmmc->MMC_CAPA |= MMC_1_8_N_3_V;

//Do MMC Bus Configuration
pmmc->MMC_CON |= MMC_OD_SET;
pmmc->MMC_HCTL |= MMC_SDVS_3V | MMC_SDBP_ON;

while (!(pmmc->MMC_HCTL & MMC_SDBP_CHKMSK))
;
//Enable internal clock [Ref: 22.5.1.5 in TRM]
pmmc->MMC_SYSCTL |= MMC_SYSCTL_ICEN;

//Wait for clock to stabilize
while (!(pmmc->MMC_SYSCTL & MMC_SYSCTL_ICS))
;

//TODO: IDLE MODE behavior skipped for now

/* Start MMC Card reset and initialization */
pmmc->MMC_CON |= MMC_INIT_SET;
pmmc->MMC_CMD = 0x0;

//We need to wait for 1 msec
wait = 0x100000;
while (wait)
wait--;
pmmc->MMC_STAT |= MMC_STAT_CLR;
pmmc->MMC_CON |= MMC_INIT_CLR;

//Clear MMC_STAT register
pmmc->MMC_STAT = 0xFFFFFFFF;

//Send CMD0
pmmc->MMC_CMD = MMC_CMD0;
pmmc->MMC_CMD = MMC_CMD5;

do {
if (pmmc->MMC_STAT & MMC_STAT_CC_TST)
{
sprint ("Found an SDIO CARD\n");
return;
}
} while (!pmmc->MMC_STAT & MMC_STAT_CTO_TST);

pmmc->MMC_SYSCTL |= MMC_SYSCTL_SRC_SET;
while (pmmc->MMC_SYSCTL & MMC_SYSCTL_SRC_SET)
;

pmmc->MMC_CMD = MMC_CMD8;


do {
if (pmmc->MMC_STAT & MMC_STAT_CC_TST)
{
sprint ("Found an SDCard\n");
return;
}
} while (!pmmc->MMC_STAT & MMC_STAT_CTO_TST);

pmmc->MMC_SYSCTL |= MMC_SYSCTL_SRC_SET;
while (pmmc->MMC_SYSCTL & MMC_SYSCTL_SRC_SET)
;

pmmc->MMC_CMD = MMC_CMD55;
pmmc->MMC_CMD = MMC_ACMD41;

do {
if (pmmc->MMC_STAT & MMC_STAT_CC_TST)
{
sprint ("Found an SD v1.1 Card\n");
return;
}
} while (!pmmc->MMC_STAT & MMC_STAT_CTO_TST);

pmmc->MMC_SYSCTL |= MMC_SYSCTL_SRC_SET;
while (pmmc->MMC_SYSCTL & MMC_SYSCTL_SRC_SET)
;

pmmc->MMC_CMD = MMC_CMD1;

do {
if (pmmc->MMC_STAT & MMC_STAT_CTO_TST)
{
sprint ("Unknown Card!!\n");
return;
}
} while (!pmmc->MMC_STAT & MMC_STAT_CC_TST);

sprint ("Found an MMC Card\n");

}


and its header file


#ifndef __MMC_H__
#define __MMC_H__

#define MMC_REG_BASE 0x4809C010

#define MMC_CLOCK_EN 0x01000000
#define MMC_SW_RESET 0x2
#define MMC_RESET_DONE 0x2
#define MMC_1_8_N_3_V 0x06000000
#define MMC_OD_SET 0x1
#define MMC_SDVS_3V 0xC00
#define MMC_SDBP_ON 0x100
#define MMC_SDBP_CHKMSK 0x100
#define MMC_SYSCTL_ICEN 0x1
#define MMC_SYSCTL_ICS 0x2
#define MMC_INIT_SET 0x1
#define MMC_INIT_CLR 0x0
#define MMC_STAT_CLR 0xFFFFFFFF
#define MMC_STAT_CC_TST 0x1
#define MMC_STAT_CTO_TST 0x00010000
#define MMC_SYSCTL_SRC_SET 0x02000000

//MMC CMDS
#define MMC_CMD0 0x00000000
#define MMC_CMD1 0x01020000
#define MMC_CMD5 0x05020000
#define MMC_CMD8 0x081A0000
#define MMC_CMD55 0x371A0000
#define MMC_ACMD41 0x291A0000

typedef struct {
unsigned int MMC_SYSCONFIG;//10
unsigned int MMC_SYSSTATUS;//14
unsigned int rsvd1[3];//18,1c,20
unsigned int MMC_CSRE;//24
unsigned int MMC_SYSTEST;//28
unsigned int MMC_CON;//2c
unsigned int MMC_PWCNT;//30
unsigned int rsvd2[52];//832d
unsigned int MMC_BLK;
unsigned int MMC_ARG;
unsigned int MMC_CMD;
unsigned int MMC_RSP10;
unsigned int MMC_RSP32;
unsigned int MMC_RSP54;
unsigned int MMC_RSP76;
unsigned int MMC_DATA;
unsigned int MMC_PSTATE;
unsigned int MMC_HCTL;
unsigned int MMC_SYSCTL;
unsigned int MMC_STAT;
unsigned int MMC_IE;
unsigned int MMC_ISE;
unsigned int MMC_AC12;
unsigned int MMC_CAPA;
unsigned int MMC_CUR_CAPA;
unsigned int rsvd3[44];
unsigned int MMC_REV;
} mmc_reg;

#endif

No comments:

Post a Comment