nds32: ftsdc010: Support ftsdc010 DM.
ftsdc010 support device tree flow. Signed-off-by: Rick Chen <rick@andestech.com>
This commit is contained in:
parent
9f678ab139
commit
252185f224
@ -12,24 +12,15 @@
|
||||
#include <part.h>
|
||||
#include <mmc.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <faraday/ftsdc010.h>
|
||||
#include "ftsdc010_mci.h"
|
||||
|
||||
#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
|
||||
#define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
|
||||
|
||||
struct ftsdc010_chip {
|
||||
void __iomem *regs;
|
||||
uint32_t wprot; /* write protected (locked) */
|
||||
uint32_t rate; /* actual SD clock in Hz */
|
||||
uint32_t sclk; /* FTSDC010 source clock in Hz */
|
||||
uint32_t fifo; /* fifo depth in bytes */
|
||||
uint32_t acmd;
|
||||
struct mmc_config cfg; /* mmc configuration */
|
||||
};
|
||||
|
||||
static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
|
||||
{
|
||||
struct ftsdc010_chip *chip = mmc->priv;
|
||||
@ -127,9 +118,8 @@ static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
|
||||
static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
|
||||
{
|
||||
int ret = -ETIMEDOUT;
|
||||
uint32_t st, ts;
|
||||
|
||||
for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
|
||||
uint32_t st, timeout = 10000000;
|
||||
while (timeout--) {
|
||||
st = readl(®s->status);
|
||||
if (!(st & mask))
|
||||
continue;
|
||||
@ -147,10 +137,16 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
|
||||
/*
|
||||
* u-boot mmc api
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
|
||||
struct mmc_data *data)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
#else
|
||||
static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||
struct mmc_data *data)
|
||||
{
|
||||
#endif
|
||||
int ret = -EOPNOTSUPP;
|
||||
uint32_t len = 0;
|
||||
struct ftsdc010_chip *chip = mmc->priv;
|
||||
@ -251,8 +247,14 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int ftsdc010_set_ios(struct udevice *dev)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
#else
|
||||
static int ftsdc010_set_ios(struct mmc *mmc)
|
||||
{
|
||||
#endif
|
||||
struct ftsdc010_chip *chip = mmc->priv;
|
||||
struct ftsdc010_mmc __iomem *regs = chip->regs;
|
||||
|
||||
@ -274,20 +276,43 @@ static int ftsdc010_set_ios(struct mmc *mmc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int ftsdc010_get_cd(struct udevice *dev)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
#else
|
||||
static int ftsdc010_get_cd(struct mmc *mmc)
|
||||
{
|
||||
#endif
|
||||
struct ftsdc010_chip *chip = mmc->priv;
|
||||
struct ftsdc010_mmc __iomem *regs = chip->regs;
|
||||
return !(readl(®s->status) & FTSDC010_STATUS_CARD_DETECT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int ftsdc010_get_wp(struct udevice *dev)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
#else
|
||||
static int ftsdc010_get_wp(struct mmc *mmc)
|
||||
{
|
||||
#endif
|
||||
struct ftsdc010_chip *chip = mmc->priv;
|
||||
struct ftsdc010_mmc __iomem *regs = chip->regs;
|
||||
if (readl(®s->status) & FTSDC010_STATUS_WRITE_PROT) {
|
||||
printf("ftsdc010: write protected\n");
|
||||
chip->wprot = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ftsdc010_init(struct mmc *mmc)
|
||||
{
|
||||
struct ftsdc010_chip *chip = mmc->priv;
|
||||
struct ftsdc010_mmc __iomem *regs = chip->regs;
|
||||
uint32_t ts;
|
||||
|
||||
if (readl(®s->status) & FTSDC010_STATUS_CARD_DETECT)
|
||||
return -ENOMEDIUM;
|
||||
|
||||
if (readl(®s->status) & FTSDC010_STATUS_WRITE_PROT) {
|
||||
printf("ftsdc010: write protected\n");
|
||||
chip->wprot = 1;
|
||||
}
|
||||
|
||||
chip->fifo = (readl(®s->feature) & 0xff) << 2;
|
||||
|
||||
/* 1. chip reset */
|
||||
@ -311,11 +336,70 @@ static int ftsdc010_init(struct mmc *mmc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
int ftsdc010_probe(struct udevice *dev)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
return ftsdc010_init(mmc);
|
||||
}
|
||||
|
||||
const struct dm_mmc_ops dm_ftsdc010_ops = {
|
||||
.send_cmd = ftsdc010_request,
|
||||
.set_ios = ftsdc010_set_ios,
|
||||
.get_cd = ftsdc010_get_cd,
|
||||
.get_wp = ftsdc010_get_wp,
|
||||
};
|
||||
|
||||
#else
|
||||
static const struct mmc_ops ftsdc010_ops = {
|
||||
.send_cmd = ftsdc010_request,
|
||||
.set_ios = ftsdc010_set_ios,
|
||||
.getcd = ftsdc010_get_cd,
|
||||
.getwp = ftsdc010_get_wp,
|
||||
.init = ftsdc010_init,
|
||||
};
|
||||
#endif
|
||||
|
||||
void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
|
||||
uint caps, u32 max_clk, u32 min_clk)
|
||||
{
|
||||
cfg->name = name;
|
||||
cfg->f_min = min_clk;
|
||||
cfg->f_max = max_clk;
|
||||
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||
cfg->host_caps = caps;
|
||||
if (buswidth == 8) {
|
||||
cfg->host_caps |= MMC_MODE_8BIT;
|
||||
cfg->host_caps &= ~MMC_MODE_4BIT;
|
||||
} else {
|
||||
cfg->host_caps |= MMC_MODE_4BIT;
|
||||
cfg->host_caps &= ~MMC_MODE_8BIT;
|
||||
}
|
||||
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
|
||||
cfg->part_type = PART_TYPE_DOS;
|
||||
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||
}
|
||||
|
||||
void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg)
|
||||
{
|
||||
switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) {
|
||||
case FTSDC010_BWR_CAPS_4BIT:
|
||||
cfg->host_caps |= MMC_MODE_4BIT;
|
||||
break;
|
||||
case FTSDC010_BWR_CAPS_8BIT:
|
||||
cfg->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK
|
||||
int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
|
||||
{
|
||||
return mmc_bind(dev, mmc, cfg);
|
||||
}
|
||||
#else
|
||||
|
||||
int ftsdc010_mmc_init(int devid)
|
||||
{
|
||||
@ -345,19 +429,11 @@ int ftsdc010_mmc_init(int devid)
|
||||
#endif
|
||||
|
||||
chip->cfg.name = "ftsdc010";
|
||||
#ifndef CONFIG_DM_MMC
|
||||
chip->cfg.ops = &ftsdc010_ops;
|
||||
#endif
|
||||
chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
|
||||
switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) {
|
||||
case FTSDC010_BWR_CAPS_4BIT:
|
||||
chip->cfg.host_caps |= MMC_MODE_4BIT;
|
||||
break;
|
||||
case FTSDC010_BWR_CAPS_8BIT:
|
||||
chip->cfg.host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
set_bus_width(regs , &chip->cfg);
|
||||
chip->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||
chip->cfg.f_max = chip->sclk / 2;
|
||||
chip->cfg.f_min = chip->sclk / 0x100;
|
||||
@ -373,3 +449,4 @@ int ftsdc010_mmc_init(int devid)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
53
drivers/mmc/ftsdc010_mci.h
Normal file
53
drivers/mmc/ftsdc010_mci.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Faraday FTSDC010 Secure Digital Memory Card Host Controller
|
||||
*
|
||||
* Copyright (C) 2011 Andes Technology Corporation
|
||||
* Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <mmc.h>
|
||||
|
||||
#ifndef __FTSDC010_MCI_H
|
||||
#define __FTSDC010_MCI_H
|
||||
|
||||
struct ftsdc010_chip {
|
||||
void __iomem *regs;
|
||||
uint32_t wprot; /* write protected (locked) */
|
||||
uint32_t rate; /* actual SD clock in Hz */
|
||||
uint32_t sclk; /* FTSDC010 source clock in Hz */
|
||||
uint32_t fifo; /* fifo depth in bytes */
|
||||
uint32_t acmd;
|
||||
struct mmc_config cfg; /* mmc configuration */
|
||||
const char *name;
|
||||
void *ioaddr;
|
||||
unsigned int caps;
|
||||
unsigned int version;
|
||||
unsigned int clock;
|
||||
unsigned int bus_hz;
|
||||
unsigned int div;
|
||||
int dev_index;
|
||||
int dev_id;
|
||||
int buswidth;
|
||||
u32 fifoth_val;
|
||||
struct mmc *mmc;
|
||||
void *priv;
|
||||
bool fifo_mode;
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
/* Export the operations to drivers */
|
||||
int ftsdc010_probe(struct udevice *dev);
|
||||
extern const struct dm_mmc_ops dm_ftsdc010_ops;
|
||||
#endif
|
||||
void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
|
||||
uint caps, u32 max_clk, u32 min_clk);
|
||||
void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg);
|
||||
|
||||
#ifdef CONFIG_BLK
|
||||
int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __FTSDC010_MCI_H */
|
Loading…
Reference in New Issue
Block a user