OMAP3: Clean up MMC code

Clean up OMAP3 MMC code:

* Convert register access to struct & readx/writex style
* Replace hardcode values by macros
* Remove macro defined twice

Signed-off-by: Dirk Behme <dirk.behme@googlemail.com>
master
Dirk Behme 16 years ago committed by Jean-Christophe PLAGNIOL-VILLARD
parent cfcdf4a9b3
commit aba45c85b2
  1. 137
      drivers/mmc/omap3_mmc.c
  2. 64
      include/asm-arm/arch-omap3/mmc_host_def.h
  3. 3
      include/asm-arm/arch-omap3/omap3.h

@ -28,6 +28,7 @@
#include <mmc.h> #include <mmc.h>
#include <part.h> #include <part.h>
#include <i2c.h> #include <i2c.h>
#include <asm/io.h>
#include <asm/arch/mmc.h> #include <asm/arch/mmc.h>
const unsigned short mmc_transspeed_val[15][4] = { const unsigned short mmc_transspeed_val[15][4] = {
@ -50,6 +51,7 @@ const unsigned short mmc_transspeed_val[15][4] = {
mmc_card_data cur_card_data; mmc_card_data cur_card_data;
static block_dev_desc_t mmc_blk_dev; static block_dev_desc_t mmc_blk_dev;
static hsmmc_t *mmc_base = (hsmmc_t *)OMAP_HSMMC_BASE;
block_dev_desc_t *mmc_get_dev(int dev) block_dev_desc_t *mmc_get_dev(int dev)
{ {
@ -60,55 +62,49 @@ void twl4030_mmc_config(void)
{ {
unsigned char data; unsigned char data;
data = 0x20; data = DEV_GRP_P1;
i2c_write(0x4B, 0x82, 1, &data, 1); i2c_write(PWRMGT_ADDR_ID4, VMMC1_DEV_GRP, 1, &data, 1);
data = 0x2; data = VMMC1_VSEL_30;
i2c_write(0x4B, 0x85, 1, &data, 1); i2c_write(PWRMGT_ADDR_ID4, VMMC1_DEDICATED, 1, &data, 1);
} }
unsigned char mmc_board_init(void) unsigned char mmc_board_init(void)
{ {
unsigned int value = 0; t2_t *t2_base = (t2_t *)T2_BASE;
twl4030_mmc_config(); twl4030_mmc_config();
value = CONTROL_PBIAS_LITE; writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 |
CONTROL_PBIAS_LITE = value | (1 << 2) | (1 << 1) | (1 << 9); PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
&t2_base->pbias_lite);
value = CONTROL_DEV_CONF0; writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL,
CONTROL_DEV_CONF0 = value | (1 << 24); &t2_base->devconf0);
return 1; return 1;
} }
void mmc_init_stream(void) void mmc_init_stream(void)
{ {
volatile unsigned int mmc_stat; writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con);
OMAP_HSMMC_CON |= INIT_INITSTREAM; writel(MMC_CMD0, &mmc_base->cmd);
while (!(readl(&mmc_base->stat) & CC_MASK));
OMAP_HSMMC_CMD = MMC_CMD0; writel(CC_MASK, &mmc_base->stat);
do {
mmc_stat = OMAP_HSMMC_STAT;
} while (!(mmc_stat & CC_MASK));
OMAP_HSMMC_STAT = CC_MASK;
OMAP_HSMMC_CMD = MMC_CMD0; writel(MMC_CMD0, &mmc_base->cmd);
do { while (!(readl(&mmc_base->stat) & CC_MASK));
mmc_stat = OMAP_HSMMC_STAT;
} while (!(mmc_stat & CC_MASK));
OMAP_HSMMC_STAT = OMAP_HSMMC_STAT; writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
OMAP_HSMMC_CON &= ~INIT_INITSTREAM;
} }
unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div) unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
{ {
unsigned int val; unsigned int val;
mmc_reg_out(OMAP_HSMMC_SYSCTL, (ICE_MASK | DTO_MASK | CEN_MASK), mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
(ICE_STOP | DTO_15THDTO | CEN_DISABLE)); (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
switch (iclk) { switch (iclk) {
case CLK_INITSEQ: case CLK_INITSEQ:
@ -123,12 +119,12 @@ unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
default: default:
return 0; return 0;
} }
mmc_reg_out(OMAP_HSMMC_SYSCTL, mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK,
ICE_MASK | CLKD_MASK, (val << CLKD_OFFSET) | ICE_OSCILLATE); (val << CLKD_OFFSET) | ICE_OSCILLATE);
while ((OMAP_HSMMC_SYSCTL & ICS_MASK) == ICS_NOTREADY) ; while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY);
OMAP_HSMMC_SYSCTL |= CEN_ENABLE; writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
return 1; return 1;
} }
@ -138,59 +134,63 @@ unsigned char mmc_init_setup(void)
mmc_board_init(); mmc_board_init();
OMAP_HSMMC_SYSCONFIG |= MMC_SOFTRESET; writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
while ((OMAP_HSMMC_SYSSTATUS & RESETDONE) == 0) ; &mmc_base->sysconfig);
while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0);
OMAP_HSMMC_SYSCTL |= SOFTRESETALL; writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
while ((OMAP_HSMMC_SYSCTL & SOFTRESETALL) != 0x0) ; while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0);
OMAP_HSMMC_HCTL = DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0; writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
OMAP_HSMMC_CAPA |= VS30_3V0SUP | VS18_1V8SUP; writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
&mmc_base->capa);
reg_val = OMAP_HSMMC_CON & RESERVED_MASK; reg_val = readl(&mmc_base->con) & RESERVED_MASK;
OMAP_HSMMC_CON = CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH |
CDP_ACTIVEHIGH | MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK |
STR_BLOCK | HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN; HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con);
mmc_clock_config(CLK_INITSEQ, 0); mmc_clock_config(CLK_INITSEQ, 0);
OMAP_HSMMC_HCTL |= SDBP_PWRON; writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
OMAP_HSMMC_IE = 0x307f0033; writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
&mmc_base->ie);
mmc_init_stream(); mmc_init_stream();
return 1; return 1;
} }
unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg, unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
unsigned int *response) unsigned int *response)
{ {
volatile unsigned int mmc_stat; unsigned int mmc_stat;
while ((OMAP_HSMMC_PSTATE & DATI_MASK) == DATI_CMDDIS) ; while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS);
OMAP_HSMMC_BLK = BLEN_512BYTESLEN | NBLK_STPCNT; writel(BLEN_512BYTESLEN | NBLK_STPCNT, &mmc_base->blk);
OMAP_HSMMC_STAT = 0xFFFFFFFF; writel(0xFFFFFFFF, &mmc_base->stat);
OMAP_HSMMC_ARG = arg; writel(arg, &mmc_base->arg);
OMAP_HSMMC_CMD = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK | writel(cmd | CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK |
CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE,
DE_DISABLE; &mmc_base->cmd);
while (1) { while (1) {
do { do {
mmc_stat = OMAP_HSMMC_STAT; mmc_stat = readl(&mmc_base->stat);
} while (mmc_stat == 0); } while (mmc_stat == 0);
if ((mmc_stat & ERRI_MASK) != 0) if ((mmc_stat & ERRI_MASK) != 0)
return (unsigned char) mmc_stat; return (unsigned char) mmc_stat;
if (mmc_stat & CC_MASK) { if (mmc_stat & CC_MASK) {
OMAP_HSMMC_STAT = CC_MASK; writel(CC_MASK, &mmc_base->stat);
response[0] = OMAP_HSMMC_RSP10; response[0] = readl(&mmc_base->rsp10);
if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) { if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) {
response[1] = OMAP_HSMMC_RSP32; response[1] = readl(&mmc_base->rsp32);
response[2] = OMAP_HSMMC_RSP54; response[2] = readl(&mmc_base->rsp54);
response[3] = OMAP_HSMMC_RSP76; response[3] = readl(&mmc_base->rsp76);
} }
break; break;
} }
@ -200,7 +200,7 @@ unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
unsigned char mmc_read_data(unsigned int *output_buf) unsigned char mmc_read_data(unsigned int *output_buf)
{ {
volatile unsigned int mmc_stat; unsigned int mmc_stat;
unsigned int read_count = 0; unsigned int read_count = 0;
/* /*
@ -208,7 +208,7 @@ unsigned char mmc_read_data(unsigned int *output_buf)
*/ */
while (1) { while (1) {
do { do {
mmc_stat = OMAP_HSMMC_STAT; mmc_stat = readl(&mmc_base->stat);
} while (mmc_stat == 0); } while (mmc_stat == 0);
if ((mmc_stat & ERRI_MASK) != 0) if ((mmc_stat & ERRI_MASK) != 0)
@ -217,19 +217,22 @@ unsigned char mmc_read_data(unsigned int *output_buf)
if (mmc_stat & BRR_MASK) { if (mmc_stat & BRR_MASK) {
unsigned int k; unsigned int k;
OMAP_HSMMC_STAT |= BRR_MASK; writel(readl(&mmc_base->stat) | BRR_MASK,
&mmc_base->stat);
for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) { for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
*output_buf = OMAP_HSMMC_DATA; *output_buf = readl(&mmc_base->data);
output_buf++; output_buf++;
read_count += 4; read_count += 4;
} }
} }
if (mmc_stat & BWR_MASK) if (mmc_stat & BWR_MASK)
OMAP_HSMMC_STAT |= BWR_MASK; writel(readl(&mmc_base->stat) | BWR_MASK,
&mmc_base->stat);
if (mmc_stat & TC_MASK) { if (mmc_stat & TC_MASK) {
OMAP_HSMMC_STAT |= TC_MASK; writel(readl(&mmc_base->stat) | TC_MASK,
&mmc_base->stat);
break; break;
} }
} }
@ -273,8 +276,8 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
mmc_card_cur->card_type = MMC_CARD; mmc_card_cur->card_type = MMC_CARD;
ocr_value |= MMC_OCR_REG_ACCESS_MODE_SECTOR; ocr_value |= MMC_OCR_REG_ACCESS_MODE_SECTOR;
ret_cmd41 = MMC_CMD1; ret_cmd41 = MMC_CMD1;
OMAP_HSMMC_CON &= ~OD; writel(readl(&mmc_base->con) & ~OD, &mmc_base->con);
OMAP_HSMMC_CON |= OPENDRAIN; writel(readl(&mmc_base->con) | OPENDRAIN, &mmc_base->con);
} }
argument = ocr_value; argument = ocr_value;
@ -342,8 +345,8 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
mmc_card_cur->RCA = ((mmc_resp_r6 *) resp)->newpublishedrca; mmc_card_cur->RCA = ((mmc_resp_r6 *) resp)->newpublishedrca;
} }
OMAP_HSMMC_CON &= ~OD; writel(readl(&mmc_base->con) & ~OD, &mmc_base->con);
OMAP_HSMMC_CON |= NOOPENDRAIN; writel(readl(&mmc_base->con) | NOOPENDRAIN, &mmc_base->con);
return 1; return 1;
} }
@ -518,7 +521,7 @@ unsigned long mmc_bread(int dev_num, unsigned long blknr, lbaint_t blkcnt,
void *dst) void *dst)
{ {
omap_mmc_read_sect(blknr, (blkcnt * MMCSD_SECTOR_SIZE), &cur_card_data, omap_mmc_read_sect(blknr, (blkcnt * MMCSD_SECTOR_SIZE), &cur_card_data,
(unsigned long *) dst); (unsigned long *) dst);
return 1; return 1;
} }

@ -25,30 +25,50 @@
#ifndef MMC_HOST_DEF_H #ifndef MMC_HOST_DEF_H
#define MMC_HOST_DEF_H #define MMC_HOST_DEF_H
/* T2 Register definitions */
#define T2_BASE 0x48002000
typedef struct t2 {
unsigned char res1[0x274];
unsigned int devconf0; /* 0x274 */
unsigned char res2[0x2A8];
unsigned int pbias_lite; /* 0x520 */
} t2_t;
#define MMCSDIO1ADPCLKISEL (1 << 24)
#define PBIASLITEPWRDNZ0 (1 << 1)
#define PBIASSPEEDCTRL0 (1 << 2)
#define PBIASLITEPWRDNZ1 (1 << 9)
/* /*
* OMAP HSMMC register definitions * OMAP HSMMC register definitions
*/ */
#define OMAP_HSMMC_SYSCONFIG (*(unsigned int *) 0x4809C010) #define OMAP_HSMMC_BASE 0x4809C000
#define OMAP_HSMMC_SYSSTATUS (*(unsigned int *) 0x4809C014)
#define OMAP_HSMMC_CON (*(unsigned int *) 0x4809C02C)
#define OMAP_HSMMC_BLK (*(unsigned int *) 0x4809C104)
#define OMAP_HSMMC_ARG (*(unsigned int *) 0x4809C108)
#define OMAP_HSMMC_CMD (*(unsigned int *) 0x4809C10C)
#define OMAP_HSMMC_RSP10 (*(unsigned int *) 0x4809C110)
#define OMAP_HSMMC_RSP32 (*(unsigned int *) 0x4809C114)
#define OMAP_HSMMC_RSP54 (*(unsigned int *) 0x4809C118)
#define OMAP_HSMMC_RSP76 (*(unsigned int *) 0x4809C11C)
#define OMAP_HSMMC_DATA (*(unsigned int *) 0x4809C120)
#define OMAP_HSMMC_PSTATE (*(unsigned int *) 0x4809C124)
#define OMAP_HSMMC_HCTL (*(unsigned int *) 0x4809C128)
#define OMAP_HSMMC_SYSCTL (*(unsigned int *) 0x4809C12C)
#define OMAP_HSMMC_STAT (*(unsigned int *) 0x4809C130)
#define OMAP_HSMMC_IE (*(unsigned int *) 0x4809C134)
#define OMAP_HSMMC_CAPA (*(unsigned int *) 0x4809C140)
/* T2 Register definitions */ typedef struct hsmmc {
#define CONTROL_DEV_CONF0 (*(unsigned int *) 0x48002274) unsigned char res1[0x10];
#define CONTROL_PBIAS_LITE (*(unsigned int *) 0x48002520) unsigned int sysconfig; /* 0x10 */
unsigned int sysstatus; /* 0x14 */
unsigned char res2[0x14];
unsigned int con; /* 0x2C */
unsigned char res3[0xD4];
unsigned int blk; /* 0x104 */
unsigned int arg; /* 0x108 */
unsigned int cmd; /* 0x10C */
unsigned int rsp10; /* 0x110 */
unsigned int rsp32; /* 0x114 */
unsigned int rsp54; /* 0x118 */
unsigned int rsp76; /* 0x11C */
unsigned int data; /* 0x120 */
unsigned int pstate; /* 0x124 */
unsigned int hctl; /* 0x128 */
unsigned int sysctl; /* 0x12C */
unsigned int stat; /* 0x130 */
unsigned int ie; /* 0x134 */
unsigned char res4[0x8];
unsigned int capa; /* 0x140 */
} hsmmc_t;
/* /*
* OMAP HS MMC Bit definitions * OMAP HS MMC Bit definitions
@ -159,8 +179,6 @@ typedef struct {
} mmc_card_data; } mmc_card_data;
#define mmc_reg_out(addr, mask, val)\ #define mmc_reg_out(addr, mask, val)\
(addr) = (((addr)) & (~(mask))) | ((val) & (mask)); writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
#define mmc_reg_out(addr, mask, val)\
(addr) = (((addr)) & (~(mask))) | ((val) & (mask));
#endif /* MMC_HOST_DEF_H */ #endif /* MMC_HOST_DEF_H */

@ -203,6 +203,8 @@ typedef struct gpio {
#define VAUX2_DEDICATED 0x79 #define VAUX2_DEDICATED 0x79
#define VAUX3_DEV_GRP 0x7A #define VAUX3_DEV_GRP 0x7A
#define VAUX3_DEDICATED 0x7D #define VAUX3_DEDICATED 0x7D
#define VMMC1_DEV_GRP 0x82
#define VMMC1_DEDICATED 0x85
#define VPLL2_DEV_GRP 0x8E #define VPLL2_DEV_GRP 0x8E
#define VPLL2_DEDICATED 0x91 #define VPLL2_DEDICATED 0x91
#define VDAC_DEV_GRP 0x96 #define VDAC_DEV_GRP 0x96
@ -215,5 +217,6 @@ typedef struct gpio {
#define VAUX3_VSEL_28 0x03 #define VAUX3_VSEL_28 0x03
#define VPLL2_VSEL_18 0x05 #define VPLL2_VSEL_18 0x05
#define VDAC_VSEL_18 0x03 #define VDAC_VSEL_18 0x03
#define VMMC1_VSEL_30 0x02
#endif #endif

Loading…
Cancel
Save