Merge git://git.denx.de/u-boot-mmc

This commit is contained in:
Tom Rini 2017-08-01 15:38:23 -04:00
commit 5c6631beb2
27 changed files with 470 additions and 199 deletions

View File

@ -164,7 +164,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
cd-inverted;
status = "okay";
};

View File

@ -236,7 +236,7 @@ static int bd82x6x_sata_probe(struct udevice *dev)
bd82x6x_sata_enable(dev);
else {
bd82x6x_sata_init(dev, pch);
ret = ahci_probe_scsi(dev);
ret = ahci_probe_scsi_pci(dev);
if (ret)
return ret;
}

View File

@ -10,7 +10,9 @@
#
obj-y += board.o
obj-$(CONFIG_SUNXI_GMAC) += gmac.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_SUNXI_AHCI) += ahci.o
endif
obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o
obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o
obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o

View File

@ -1,5 +1,6 @@
#include <common.h>
#include <ahci.h>
#include <dm.h>
#include <scsi.h>
#include <errno.h>
#include <asm/io.h>
@ -13,9 +14,8 @@
/* This magic PHY initialisation was taken from the Allwinner releases
* and Linux driver, but is completely undocumented.
*/
static int sunxi_ahci_phy_init(u32 base)
static int sunxi_ahci_phy_init(u8 *reg_base)
{
u8 *reg_base = (u8 *)base;
u32 reg_val;
int timeout;
@ -70,10 +70,65 @@ static int sunxi_ahci_phy_init(u32 base)
return 0;
}
#ifndef CONFIG_DM_SCSI
void scsi_init(void)
{
if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0)
if (sunxi_ahci_phy_init((u8 *)SUNXI_SATA_BASE) < 0)
return;
ahci_init((void __iomem *)SUNXI_SATA_BASE);
}
#else
static int sunxi_sata_probe(struct udevice *dev)
{
ulong base;
u8 *reg;
int ret;
base = dev_read_addr(dev);
if (base == FDT_ADDR_T_NONE) {
debug("%s: Failed to find address (err=%d\n)", __func__, ret);
return -EINVAL;
}
reg = (u8 *)base;
ret = sunxi_ahci_phy_init(reg);
if (ret) {
debug("%s: Failed to init phy (err=%d\n)", __func__, ret);
return ret;
}
ret = ahci_probe_scsi(dev, base);
if (ret) {
debug("%s: Failed to probe (err=%d\n)", __func__, ret);
return ret;
}
return 0;
}
static int sunxi_sata_bind(struct udevice *dev)
{
struct udevice *scsi_dev;
int ret;
ret = ahci_bind_scsi(dev, &scsi_dev);
if (ret) {
debug("%s: Failed to bind (err=%d\n)", __func__, ret);
return ret;
}
return 0;
}
static const struct udevice_id sunxi_ahci_ids[] = {
{ .compatible = "allwinner,sun4i-a10-ahci" },
{ }
};
U_BOOT_DRIVER(ahci_sunxi_drv) = {
.name = "ahci_sunxi",
.id = UCLASS_AHCI,
.of_match = sunxi_ahci_ids,
.bind = sunxi_sata_bind,
.probe = sunxi_sata_probe,
};
#endif

View File

@ -1464,14 +1464,11 @@ int fdt_verify_alias_address(void *fdt, int anode, const char *alias, u64 addr)
u64 fdt_get_base_address(const void *fdt, int node)
{
int size;
u32 naddr;
const fdt32_t *prop;
naddr = fdt_address_cells(fdt, node);
prop = fdt_getprop(fdt, node, "reg", &size);
prop = fdt_getprop(fdt, node, "ranges", &size);
return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0;
return prop ? fdt_translate_address(fdt, node, prop) : 0;
}
/*

View File

@ -115,7 +115,7 @@ static int spl_mmc_get_device_index(u32 boot_device)
static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
{
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
struct udevice *dev;
#endif
int err, mmc_dev;
@ -132,7 +132,7 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
return err;
}
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev);
if (!err)
*mmcp = mmc_get_mmc_dev(dev);

View File

@ -15,7 +15,12 @@ CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_ISO_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_SCSI=y
# CONFIG_SPL_BLK is not set
CONFIG_DM_MMC=y
# CONFIG_SPL_DM_MMC is not set
# CONFIG_SPL_DM_MMC_OPS is not set
CONFIG_ETH_DESIGNWARE=y
CONFIG_SUN7I_GMAC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_USB_EHCI_HCD=y

View File

@ -20,24 +20,6 @@ config SATA
See also CMD_SATA which provides command-line support.
config SCSI
bool "Support SCSI controllers"
help
This enables support for SCSI (Small Computer System Interface),
a parallel interface widely used with storage peripherals such as
hard drives and optical drives. The SCSI standards define physical
interfaces as well as protocols for controlling devices and
tranferring data.
config DM_SCSI
bool "Support SCSI controllers with driver model"
depends on BLK
help
This option enables the SCSI (Small Computer System Interface) uclass
which supports SCSI and SATA HDDs. For every device configuration
(IDs/LUNs) a block device is created with RAW read/write and
filesystem support.
menu "SATA/SCSI device support"
config SATA_CEVA

View File

@ -6,9 +6,11 @@
*/
#include <common.h>
#include <ahci.h>
#include <dm.h>
UCLASS_DRIVER(ahci) = {
.id = UCLASS_AHCI,
.name = "ahci",
.per_device_auto_alloc_size = sizeof(struct ahci_uc_priv),
};

View File

@ -431,7 +431,7 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv)
cap2 & (1 << 0) ? "boh " : "");
}
#ifndef CONFIG_SCSI_AHCI_PLAT
#if defined(CONFIG_DM_SCSI) || !defined(CONFIG_SCSI_AHCI_PLAT)
# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev)
# else
@ -935,7 +935,7 @@ static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
{
struct ahci_uc_priv *uc_priv;
#ifdef CONFIG_DM_SCSI
uc_priv = dev_get_uclass_priv(dev);
uc_priv = dev_get_uclass_priv(dev->parent);
#else
uc_priv = probe_ent;
#endif
@ -1158,11 +1158,8 @@ int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp)
return 0;
}
int ahci_probe_scsi(struct udevice *ahci_dev)
int ahci_probe_scsi(struct udevice *ahci_dev, ulong base)
{
#ifdef CONFIG_SCSI_AHCI_PLAT
return -ENOSYS; /* TODO(sjg@chromium.org): Support non-PCI AHCI */
#else
struct ahci_uc_priv *uc_priv;
struct scsi_platdata *uc_plat;
struct udevice *dev;
@ -1172,22 +1169,33 @@ int ahci_probe_scsi(struct udevice *ahci_dev)
if (!dev)
return -ENODEV;
uc_plat = dev_get_uclass_platdata(dev);
uc_plat->base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
uc_plat->base = base;
uc_plat->max_lun = 1;
uc_plat->max_id = 2;
uc_priv = dev_get_uclass_priv(dev);
uc_priv = dev_get_uclass_priv(ahci_dev);
ret = ahci_init_one(uc_priv, dev);
if (ret)
return ret;
ret = ahci_start_ports(uc_priv);
if (ret)
return ret;
#endif
return 0;
}
#ifdef CONFIG_DM_PCI
int ahci_probe_scsi_pci(struct udevice *ahci_dev)
{
ulong base;
base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
return ahci_probe_scsi(ahci_dev, base);
}
#endif
struct scsi_ops scsi_ops = {
.exec = ahci_scsi_exec,
.bus_reset = ahci_scsi_bus_reset,

View File

@ -10,6 +10,18 @@ config BLK
be partitioned into several areas, called 'partitions' in U-Boot.
A filesystem can be placed in each partition.
config SPL_BLK
bool "Support block devices in SPL"
depends on SPL_DM && BLK
default y
help
Enable support for block devices, such as SCSI, MMC and USB
flash sticks. These provide a block-level interface which permits
reading, writing and (in some cases) erasing blocks. Block
devices often have a partition table which allows the device to
be partitioned into several areas, called 'partitions' in U-Boot.
A filesystem can be placed in each partition.
config BLOCK_CACHE
bool "Use block device cache"
default n

View File

@ -5,9 +5,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_BLK) += blk-uclass.o
obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o
ifndef CONFIG_BLK
ifndef CONFIG_$(SPL_)BLK
obj-y += blk_legacy.o
endif

View File

@ -30,6 +30,27 @@ config DM_MMC_OPS
option will be removed as soon as all DM_MMC drivers use it, as it
will the only supported behaviour.
config SPL_DM_MMC
bool "Enable MMC controllers using Driver Model in SPL"
depends on SPL_DM && DM_MMC
default y
help
This enables the MultiMediaCard (MMC) uclass which supports MMC and
Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.)
and non-removable (e.g. eMMC chip) devices are supported. These
appear as block devices in U-Boot and can support filesystems such
as EXT4 and FAT.
config SPL_DM_MMC_OPS
bool "Support MMC controller operations using Driver Model in SPL"
depends on SPL_DM && DM_MMC_OPS
default y
help
Driver model provides a means of supporting device operations. This
option moves MMC operations under the control of driver model. The
option will be removed as soon as all DM_MMC drivers use it, as it
will the only supported behaviour.
if MMC
config SPL_MMC_TINY

View File

@ -6,9 +6,9 @@
#
obj-y += mmc.o
obj-$(CONFIG_DM_MMC) += mmc-uclass.o
obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
ifndef CONFIG_BLK
ifndef CONFIG_$(SPL_)BLK
obj-y += mmc_legacy.o
endif

View File

@ -15,7 +15,7 @@
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_DM_MMC_OPS
#if CONFIG_IS_ENABLED(DM_MMC_OPS)
int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
@ -91,7 +91,7 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev)
return upriv->mmc;
}
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
struct mmc *find_mmc_device(int dev_num)
{
struct udevice *dev, *mmc_dev;
@ -198,7 +198,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
struct udevice *bdev;
int ret, devnum = -1;
#ifdef CONFIG_DM_MMC_OPS
#if CONFIG_IS_ENABLED(DM_MMC_OPS)
if (!mmc_get_ops(dev))
return -ENOSYS;
#endif

View File

@ -53,7 +53,7 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
}
#endif
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
__weak int board_mmc_getwp(struct mmc *mmc)
{
return -1;
@ -149,7 +149,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
}
#endif
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
{
int ret;
@ -261,14 +261,14 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
return blkcnt;
}
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
#else
ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
void *dst)
#endif
{
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
int dev_num = block_dev->devnum;
@ -839,7 +839,7 @@ int mmc_hwpart_config(struct mmc *mmc,
return 0;
}
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
int mmc_getcd(struct mmc *mmc)
{
int cd;
@ -1075,7 +1075,7 @@ static const u8 multipliers[] = {
80,
};
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
static void mmc_set_ios(struct mmc *mmc)
{
if (mmc->cfg->ops->set_ios)
@ -1608,7 +1608,7 @@ static int mmc_send_if_cond(struct mmc *mmc)
return 0;
}
#ifndef CONFIG_DM_MMC
#if !CONFIG_IS_ENABLED(DM_MMC)
/* board-specific MMC power initializations. */
__weak void board_mmc_power_init(void)
{
@ -1617,7 +1617,7 @@ __weak void board_mmc_power_init(void)
static int mmc_power_init(struct mmc *mmc)
{
#if defined(CONFIG_DM_MMC)
#if CONFIG_IS_ENABLED(DM_MMC)
#if defined(CONFIG_DM_REGULATOR) && !defined(CONFIG_SPL_BUILD)
struct udevice *vmmc_supply;
int ret;
@ -1652,7 +1652,7 @@ int mmc_start_init(struct mmc *mmc)
/* we pretend there's no card when init is NULL */
no_card = mmc_getcd(mmc) == 0;
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
no_card = no_card || (mmc->cfg->ops->init == NULL);
#endif
if (no_card) {
@ -1673,7 +1673,7 @@ int mmc_start_init(struct mmc *mmc)
if (err)
return err;
#ifdef CONFIG_DM_MMC_OPS
#if CONFIG_IS_ENABLED(DM_MMC_OPS)
/* The device has already been probed ready for use */
#else
/* made sure it's not NULL earlier */
@ -1739,7 +1739,7 @@ int mmc_init(struct mmc *mmc)
{
int err = 0;
__maybe_unused unsigned start;
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
upriv->mmc = mmc;
@ -1783,12 +1783,12 @@ void mmc_set_preinit(struct mmc *mmc, int preinit)
mmc->preinit = preinit;
}
#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
#if CONFIG_IS_ENABLED(DM_MMC) && defined(CONFIG_SPL_BUILD)
static int mmc_probe(bd_t *bis)
{
return 0;
}
#elif defined(CONFIG_DM_MMC)
#elif CONFIG_IS_ENABLED(DM_MMC)
static int mmc_probe(bd_t *bis)
{
int ret, i;
@ -1835,7 +1835,7 @@ int mmc_initialize(bd_t *bis)
return 0;
initialized = 1;
#ifndef CONFIG_BLK
#if !CONFIG_IS_ENABLED(BLK)
#if !CONFIG_IS_ENABLED(MMC_TINY)
mmc_list_init();
#endif

View File

@ -150,7 +150,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
cfg->f_max == 0 || cfg->b_max == 0)
return NULL;
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
if (cfg->ops == NULL || cfg->ops->send_cmd == NULL)
return NULL;
#endif

View File

@ -20,7 +20,7 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len);
void mmc_adapter_card_type_ident(void);
#endif
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
void *dst);
#else
@ -30,7 +30,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
const void *src);
ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt);
@ -44,7 +44,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
/* declare dummies to reduce code size. */
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
static inline unsigned long mmc_berase(struct udevice *dev,
lbaint_t start, lbaint_t blkcnt)
{

View File

@ -62,11 +62,11 @@ struct omap2_mmc_platform_config {
struct omap_hsmmc_data {
struct hsmmc *base_addr;
#ifndef CONFIG_DM_MMC
#if !CONFIG_IS_ENABLED(DM_MMC)
struct mmc_config cfg;
#endif
#ifdef OMAP_HSMMC_USE_GPIO
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
struct gpio_desc cd_gpio; /* Change Detect GPIO */
struct gpio_desc wp_gpio; /* Write Protect GPIO */
bool cd_inverted;
@ -86,7 +86,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
{
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
return dev_get_priv(mmc->dev);
#else
return (struct omap_hsmmc_data *)mmc->priv;
@ -94,7 +94,7 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
}
static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc)
{
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
struct omap_hsmmc_plat *plat = dev_get_platdata(mmc->dev);
return &plat->cfg;
#else
@ -102,7 +102,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc)
#endif
}
#if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC)
#if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC)
static int omap_mmc_setup_gpio_in(int gpio, const char *label)
{
int ret;
@ -326,7 +326,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
}
}
}
#ifndef CONFIG_DM_MMC
#if !CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
@ -564,7 +564,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
return 0;
}
#ifndef CONFIG_DM_MMC
#if !CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_set_ios(struct mmc *mmc)
{
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@ -630,7 +630,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
}
#ifdef OMAP_HSMMC_USE_GPIO
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_getcd(struct udevice *dev)
{
struct omap_hsmmc_data *priv = dev_get_priv(dev);
@ -688,7 +688,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc)
#endif
#endif
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
static const struct dm_mmc_ops omap_hsmmc_ops = {
.send_cmd = omap_hsmmc_send_cmd,
.set_ios = omap_hsmmc_set_ios,
@ -709,7 +709,7 @@ static const struct mmc_ops omap_hsmmc_ops = {
};
#endif
#ifndef CONFIG_DM_MMC
#if !CONFIG_IS_ENABLED(DM_MMC)
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio)
{

View File

@ -9,6 +9,7 @@
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <mmc.h>
@ -19,16 +20,23 @@
#include <asm/arch/mmc.h>
#include <asm-generic/gpio.h>
struct sunxi_mmc_host {
struct sunxi_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
};
struct sunxi_mmc_priv {
unsigned mmc_no;
uint32_t *mclkreg;
unsigned fatal_err;
struct gpio_desc cd_gpio; /* Change Detect GPIO */
struct sunxi_mmc *reg;
struct mmc_config cfg;
};
#if !CONFIG_IS_ENABLED(DM_MMC)
/* support 4 mmc hosts */
struct sunxi_mmc_host mmc_host[4];
struct sunxi_mmc_priv mmc_host[4];
static int sunxi_mmc_getcd_gpio(int sdc_no)
{
@ -43,7 +51,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no)
static int mmc_resource_init(int sdc_no)
{
struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int cd_pin, ret = 0;
@ -51,26 +59,26 @@ static int mmc_resource_init(int sdc_no)
switch (sdc_no) {
case 0:
mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
mmchost->mclkreg = &ccm->sd0_clk_cfg;
priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
priv->mclkreg = &ccm->sd0_clk_cfg;
break;
case 1:
mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
mmchost->mclkreg = &ccm->sd1_clk_cfg;
priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
priv->mclkreg = &ccm->sd1_clk_cfg;
break;
case 2:
mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
mmchost->mclkreg = &ccm->sd2_clk_cfg;
priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
priv->mclkreg = &ccm->sd2_clk_cfg;
break;
case 3:
mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
mmchost->mclkreg = &ccm->sd3_clk_cfg;
priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
priv->mclkreg = &ccm->sd3_clk_cfg;
break;
default:
printf("Wrong mmc number %d\n", sdc_no);
return -1;
}
mmchost->mmc_no = sdc_no;
priv->mmc_no = sdc_no;
cd_pin = sunxi_mmc_getcd_gpio(sdc_no);
if (cd_pin >= 0) {
@ -83,8 +91,9 @@ static int mmc_resource_init(int sdc_no)
return ret;
}
#endif
static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
{
unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
@ -112,8 +121,8 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
}
if (n > 3) {
printf("mmc %u error cannot set clock to %u\n",
mmchost->mmc_no, hz);
printf("mmc %u error cannot set clock to %u\n", priv->mmc_no,
hz);
return -1;
}
@ -145,126 +154,101 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) |
CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_OCLK_DLY(oclk_dly) |
CCM_MMC_CTRL_M(div), mmchost->mclkreg);
CCM_MMC_CTRL_M(div), priv->mclkreg);
debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n",
mmchost->mmc_no, hz, pll_hz, 1u << n, div,
pll_hz / (1u << n) / div);
priv->mmc_no, hz, pll_hz, 1u << n, div, pll_hz / (1u << n) / div);
return 0;
}
static int mmc_clk_io_on(int sdc_no)
static int mmc_update_clk(struct sunxi_mmc_priv *priv)
{
struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
debug("init mmc %d clock and io\n", sdc_no);
/* config ahb clock */
setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
#ifdef CONFIG_SUNXI_GEN_SUN6I
/* unassert reset */
setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
#endif
#if defined(CONFIG_MACH_SUN9I)
/* sun9i has a mmc-common module, also set the gate and reset there */
writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
#endif
return mmc_set_mod_clk(mmchost, 24000000);
}
static int mmc_update_clk(struct mmc *mmc)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
unsigned int cmd;
unsigned timeout_msecs = 2000;
cmd = SUNXI_MMC_CMD_START |
SUNXI_MMC_CMD_UPCLK_ONLY |
SUNXI_MMC_CMD_WAIT_PRE_OVER;
writel(cmd, &mmchost->reg->cmd);
while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) {
writel(cmd, &priv->reg->cmd);
while (readl(&priv->reg->cmd) & SUNXI_MMC_CMD_START) {
if (!timeout_msecs--)
return -1;
udelay(1000);
}
/* clock update sets various irq status bits, clear these */
writel(readl(&mmchost->reg->rint), &mmchost->reg->rint);
writel(readl(&priv->reg->rint), &priv->reg->rint);
return 0;
}
static int mmc_config_clock(struct mmc *mmc)
static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
unsigned rval = readl(&mmchost->reg->clkcr);
unsigned rval = readl(&priv->reg->clkcr);
/* Disable Clock */
rval &= ~SUNXI_MMC_CLK_ENABLE;
writel(rval, &mmchost->reg->clkcr);
if (mmc_update_clk(mmc))
writel(rval, &priv->reg->clkcr);
if (mmc_update_clk(priv))
return -1;
/* Set mod_clk to new rate */
if (mmc_set_mod_clk(mmchost, mmc->clock))
if (mmc_set_mod_clk(priv, mmc->clock))
return -1;
/* Clear internal divider */
rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
writel(rval, &mmchost->reg->clkcr);
writel(rval, &priv->reg->clkcr);
/* Re-enable Clock */
rval |= SUNXI_MMC_CLK_ENABLE;
writel(rval, &mmchost->reg->clkcr);
if (mmc_update_clk(mmc))
writel(rval, &priv->reg->clkcr);
if (mmc_update_clk(priv))
return -1;
return 0;
}
static int sunxi_mmc_set_ios(struct mmc *mmc)
static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv,
struct mmc *mmc)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
debug("set ios: bus_width: %x, clock: %d\n",
mmc->bus_width, mmc->clock);
/* Change clock first */
if (mmc->clock && mmc_config_clock(mmc) != 0) {
mmchost->fatal_err = 1;
if (mmc->clock && mmc_config_clock(priv, mmc) != 0) {
priv->fatal_err = 1;
return -EINVAL;
}
/* Change bus width */
if (mmc->bus_width == 8)
writel(0x2, &mmchost->reg->width);
writel(0x2, &priv->reg->width);
else if (mmc->bus_width == 4)
writel(0x1, &mmchost->reg->width);
writel(0x1, &priv->reg->width);
else
writel(0x0, &mmchost->reg->width);
writel(0x0, &priv->reg->width);
return 0;
}
#if !CONFIG_IS_ENABLED(DM_MMC)
static int sunxi_mmc_core_init(struct mmc *mmc)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
struct sunxi_mmc_priv *priv = mmc->priv;
/* Reset controller */
writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl);
writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
udelay(1000);
return 0;
}
#endif
static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
struct mmc_data *data)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
const int reading = !!(data->flags & MMC_DATA_READ);
const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
SUNXI_MMC_STATUS_FIFO_FULL;
@ -276,32 +260,31 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
timeout_usecs = 2000000;
/* Always read / write data through the CPU */
setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
for (i = 0; i < (byte_cnt >> 2); i++) {
while (readl(&mmchost->reg->status) & status_bit) {
while (readl(&priv->reg->status) & status_bit) {
if (!timeout_usecs--)
return -1;
udelay(1);
}
if (reading)
buff[i] = readl(&mmchost->reg->fifo);
buff[i] = readl(&priv->reg->fifo);
else
writel(buff[i], &mmchost->reg->fifo);
writel(buff[i], &priv->reg->fifo);
}
return 0;
}
static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
unsigned int done_bit, const char *what)
static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc,
uint timeout_msecs, uint done_bit, const char *what)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
unsigned int status;
do {
status = readl(&mmchost->reg->rint);
status = readl(&priv->reg->rint);
if (!timeout_msecs-- ||
(status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) {
debug("%s timeout %x\n", what,
@ -314,17 +297,17 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
return 0;
}
static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
unsigned int cmdval = SUNXI_MMC_CMD_START;
unsigned int timeout_msecs;
int error = 0;
unsigned int status = 0;
unsigned int bytecnt = 0;
if (mmchost->fatal_err)
if (priv->fatal_err)
return -1;
if (cmd->resp_type & MMC_RSP_BUSY)
debug("mmc cmd %d check rsp busy\n", cmd->cmdidx);
@ -351,16 +334,16 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
cmdval |= SUNXI_MMC_CMD_WRITE;
if (data->blocks > 1)
cmdval |= SUNXI_MMC_CMD_AUTO_STOP;
writel(data->blocksize, &mmchost->reg->blksz);
writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt);
writel(data->blocksize, &priv->reg->blksz);
writel(data->blocks * data->blocksize, &priv->reg->bytecnt);
}
debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no,
debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", priv->mmc_no,
cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
writel(cmd->cmdarg, &mmchost->reg->arg);
writel(cmd->cmdarg, &priv->reg->arg);
if (!data)
writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
/*
* transfer data and check status
@ -372,24 +355,25 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
bytecnt = data->blocksize * data->blocks;
debug("trans data %d bytes\n", bytecnt);
writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
ret = mmc_trans_data_by_cpu(mmc, data);
writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
ret = mmc_trans_data_by_cpu(priv, mmc, data);
if (ret) {
error = readl(&mmchost->reg->rint) & \
error = readl(&priv->reg->rint) &
SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT;
error = -ETIMEDOUT;
goto out;
}
}
error = mmc_rint_wait(mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE, "cmd");
error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE,
"cmd");
if (error)
goto out;
if (data) {
timeout_msecs = 120;
debug("cacl timeout %x msec\n", timeout_msecs);
error = mmc_rint_wait(mmc, timeout_msecs,
error = mmc_rint_wait(priv, mmc, timeout_msecs,
data->blocks > 1 ?
SUNXI_MMC_RINT_AUTO_COMMAND_DONE :
SUNXI_MMC_RINT_DATA_OVER,
@ -401,7 +385,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
if (cmd->resp_type & MMC_RSP_BUSY) {
timeout_msecs = 2000;
do {
status = readl(&mmchost->reg->status);
status = readl(&priv->reg->status);
if (!timeout_msecs--) {
debug("busy timeout\n");
error = -ETIMEDOUT;
@ -412,35 +396,51 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
if (cmd->resp_type & MMC_RSP_136) {
cmd->response[0] = readl(&mmchost->reg->resp3);
cmd->response[1] = readl(&mmchost->reg->resp2);
cmd->response[2] = readl(&mmchost->reg->resp1);
cmd->response[3] = readl(&mmchost->reg->resp0);
cmd->response[0] = readl(&priv->reg->resp3);
cmd->response[1] = readl(&priv->reg->resp2);
cmd->response[2] = readl(&priv->reg->resp1);
cmd->response[3] = readl(&priv->reg->resp0);
debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n",
cmd->response[3], cmd->response[2],
cmd->response[1], cmd->response[0]);
} else {
cmd->response[0] = readl(&mmchost->reg->resp0);
cmd->response[0] = readl(&priv->reg->resp0);
debug("mmc resp 0x%08x\n", cmd->response[0]);
}
out:
if (error < 0) {
writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl);
mmc_update_clk(mmc);
writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
mmc_update_clk(priv);
}
writel(0xffffffff, &mmchost->reg->rint);
writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
&mmchost->reg->gctrl);
writel(0xffffffff, &priv->reg->rint);
writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
&priv->reg->gctrl);
return error;
}
static int sunxi_mmc_getcd(struct mmc *mmc)
#if !CONFIG_IS_ENABLED(DM_MMC)
static int sunxi_mmc_set_ios_legacy(struct mmc *mmc)
{
struct sunxi_mmc_host *mmchost = mmc->priv;
struct sunxi_mmc_priv *priv = mmc->priv;
return sunxi_mmc_set_ios_common(priv, mmc);
}
static int sunxi_mmc_send_cmd_legacy(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
struct sunxi_mmc_priv *priv = mmc->priv;
return sunxi_mmc_send_cmd_common(priv, mmc, cmd, data);
}
static int sunxi_mmc_getcd_legacy(struct mmc *mmc)
{
struct sunxi_mmc_priv *priv = mmc->priv;
int cd_pin;
cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no);
cd_pin = sunxi_mmc_getcd_gpio(priv->mmc_no);
if (cd_pin < 0)
return 1;
@ -448,17 +448,20 @@ static int sunxi_mmc_getcd(struct mmc *mmc)
}
static const struct mmc_ops sunxi_mmc_ops = {
.send_cmd = sunxi_mmc_send_cmd,
.set_ios = sunxi_mmc_set_ios,
.send_cmd = sunxi_mmc_send_cmd_legacy,
.set_ios = sunxi_mmc_set_ios_legacy,
.init = sunxi_mmc_core_init,
.getcd = sunxi_mmc_getcd,
.getcd = sunxi_mmc_getcd_legacy,
};
struct mmc *sunxi_mmc_init(int sdc_no)
{
struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
struct mmc_config *cfg = &priv->cfg;
int ret;
memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host));
memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
cfg->name = "SUNXI SD/MMC";
cfg->ops = &sunxi_mmc_ops;
@ -478,7 +481,143 @@ struct mmc *sunxi_mmc_init(int sdc_no)
if (mmc_resource_init(sdc_no) != 0)
return NULL;
mmc_clk_io_on(sdc_no);
/* config ahb clock */
debug("init mmc %d clock and io\n", sdc_no);
setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
return mmc_create(cfg, &mmc_host[sdc_no]);
#ifdef CONFIG_SUNXI_GEN_SUN6I
/* unassert reset */
setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
#endif
#if defined(CONFIG_MACH_SUN9I)
/* sun9i has a mmc-common module, also set the gate and reset there */
writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
#endif
ret = mmc_set_mod_clk(priv, 24000000);
if (ret)
return NULL;
return mmc_create(cfg, mmc_host);
}
#else
static int sunxi_mmc_set_ios(struct udevice *dev)
{
struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
struct sunxi_mmc_priv *priv = dev_get_priv(dev);
return sunxi_mmc_set_ios_common(priv, &plat->mmc);
}
static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
struct sunxi_mmc_priv *priv = dev_get_priv(dev);
return sunxi_mmc_send_cmd_common(priv, &plat->mmc, cmd, data);
}
static int sunxi_mmc_getcd(struct udevice *dev)
{
struct sunxi_mmc_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->cd_gpio))
return dm_gpio_get_value(&priv->cd_gpio);
return 1;
}
static const struct dm_mmc_ops sunxi_mmc_ops = {
.send_cmd = sunxi_mmc_send_cmd,
.set_ios = sunxi_mmc_set_ios,
.get_cd = sunxi_mmc_getcd,
};
static int sunxi_mmc_probe(struct udevice *dev)
{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
struct sunxi_mmc_priv *priv = dev_get_priv(dev);
struct mmc_config *cfg = &plat->cfg;
struct ofnode_phandle_args args;
u32 *gate_reg;
int bus_width, ret;
cfg->name = dev->name;
bus_width = dev_read_u32_default(dev, "bus-width", 1);
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->host_caps = 0;
if (bus_width == 8)
cfg->host_caps |= MMC_MODE_8BIT;
if (bus_width >= 4)
cfg->host_caps |= MMC_MODE_4BIT;
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
cfg->f_min = 400000;
cfg->f_max = 52000000;
priv->reg = (void *)dev_read_addr(dev);
/* We don't have a sunxi clock driver so find the clock address here */
ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
1, &args);
if (ret)
return ret;
priv->mclkreg = (u32 *)ofnode_get_addr(args.node);
ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
0, &args);
if (ret)
return ret;
gate_reg = (u32 *)ofnode_get_addr(args.node);
setbits_le32(gate_reg, 1 << args.args[0]);
priv->mmc_no = args.args[0] - 8;
ret = mmc_set_mod_clk(priv, 24000000);
if (ret)
return ret;
/* This GPIO is optional */
if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
GPIOD_IS_IN)) {
int cd_pin = gpio_get_number(&priv->cd_gpio);
sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
}
upriv->mmc = &plat->mmc;
/* Reset controller */
writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
udelay(1000);
return 0;
}
static int sunxi_mmc_bind(struct udevice *dev)
{
struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
return mmc_bind(dev, &plat->mmc, &plat->cfg);
}
static const struct udevice_id sunxi_mmc_ids[] = {
{ .compatible = "allwinner,sun5i-a13-mmc" },
{ }
};
U_BOOT_DRIVER(sunxi_mmc_drv) = {
.name = "sunxi_mmc",
.id = UCLASS_MMC,
.of_match = sunxi_mmc_ids,
.bind = sunxi_mmc_bind,
.probe = sunxi_mmc_probe,
.ops = &sunxi_mmc_ops,
.platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat),
.priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv),
};
#endif

View File

@ -50,10 +50,9 @@ int palmas_mmc1_poweron_ldo(uint voltage)
int ret;
/*
* Currently valid for the dra7xx_evm board:
* Set TPS659038 LDO1 to 3.0 V
* Set TPS659038 LDO1 to 3.0 V or 1.8V
*/
val = LDO_VOLT_3V0;
ret = palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_VOLTAGE, val);
ret = palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_VOLTAGE, voltage);
if (ret) {
printf("tps65903x: could not set LDO1 voltage.\n");
return ret;

View File

@ -163,6 +163,38 @@ static int palmas_smps_val(struct udevice *dev, int op, int *uV)
return pmic_reg_write(dev->parent, adr, ret);
}
static int palmas_ldo_bypass_enable(struct udevice *dev, bool enabled)
{
int type = dev_get_driver_data(dev_get_parent(dev));
struct dm_regulator_uclass_platdata *p;
unsigned int adr;
int reg;
if (type == TPS65917) {
/* bypass available only on LDO1 and LDO2 */
if (dev->driver_data > 2)
return -ENOTSUPP;
} else if (type == TPS659038) {
/* bypass available only on LDO9 */
if (dev->driver_data != 9)
return -ENOTSUPP;
}
p = dev_get_uclass_platdata(dev);
adr = p->ctrl_reg;
reg = pmic_reg_read(dev->parent, adr);
if (reg < 0)
return reg;
if (enabled)
reg |= PALMAS_LDO_BYPASS_EN;
else
reg &= ~PALMAS_LDO_BYPASS_EN;
return pmic_reg_write(dev->parent, adr, reg);
}
static int palmas_ldo_enable(struct udevice *dev, int op, bool *enable)
{
int ret;
@ -194,6 +226,10 @@ static int palmas_ldo_enable(struct udevice *dev, int op, bool *enable)
ret = pmic_reg_write(dev->parent, adr, ret);
if (ret)
return ret;
ret = palmas_ldo_bypass_enable(dev, false);
if (ret && (ret != -ENOTSUPP))
return ret;
}
return 0;

View File

@ -451,7 +451,7 @@ static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc)
dev_desc->product[0] = 0;
dev_desc->revision[0] = 0;
dev_desc->removable = false;
#ifndef CONFIG_BLK
#if !CONFIG_IS_ENABLED(BLK)
dev_desc->block_read = scsi_read;
dev_desc->block_write = scsi_write;
#endif

View File

@ -218,8 +218,20 @@ int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp);
* devices it finds.
*
* @ahci_dev: AHCI parent device
* @base: Base address of AHCI port
* @return 0 if OK, -ve on error
*/
int ahci_probe_scsi(struct udevice *ahci_dev);
int ahci_probe_scsi(struct udevice *ahci_dev, ulong base);
/**
* ahci_probe_scsi_pci() - probe and scan the attached SCSI bus on PCI
*
* Note that the SCSI device will itself bind block devices for any storage
* devices it finds.
*
* @ahci_dev: AHCI parent device
* @return 0 if OK, -ve on error
*/
int ahci_probe_scsi_pci(struct udevice *ahci_dev);
#endif

View File

@ -62,7 +62,7 @@ struct blk_desc {
char vendor[40+1]; /* IDE model, SCSI Vendor */
char product[20+1]; /* IDE Serial no, SCSI product */
char revision[8+1]; /* firmware revision */
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
/*
* For now we have a few functions which take struct blk_desc as a
* parameter. This field allows them to look up the associated
@ -174,7 +174,7 @@ static inline void blkcache_invalidate(int iftype, int dev) {}
#endif
#ifdef CONFIG_BLK
#if CONFIG_IS_ENABLED(BLK)
struct udevice;
/* Operations on block devices */

View File

@ -321,7 +321,7 @@ struct mmc_data {
/* forward decl. */
struct mmc;
#ifdef CONFIG_DM_MMC_OPS
#if CONFIG_IS_ENABLED(DM_MMC_OPS)
struct dm_mmc_ops {
/**
* send_cmd() - Send a command to the MMC device
@ -385,7 +385,7 @@ struct mmc_ops {
struct mmc_config {
const char *name;
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
const struct mmc_ops *ops;
#endif
uint host_caps;
@ -409,7 +409,7 @@ struct sd_ssr {
* TODO struct mmc should be in mmc_private but it's hard to fix right now
*/
struct mmc {
#ifndef CONFIG_BLK
#if !CONFIG_IS_ENABLED(BLK)
struct list_head link;
#endif
const struct mmc_config *cfg; /* provided configuration */
@ -444,14 +444,14 @@ struct mmc {
u64 capacity_gp[4];
u64 enh_user_start;
u64 enh_user_size;
#ifndef CONFIG_BLK
#if !CONFIG_IS_ENABLED(BLK)
struct blk_desc block_dev;
#endif
char op_cond_pending; /* 1 if we are waiting on an op_cond command */
char init_in_progress; /* 1 if we have done mmc_start_init() */
char preinit; /* start init as early as possible */
int ddr_mode;
#ifdef CONFIG_DM_MMC
#if CONFIG_IS_ENABLED(DM_MMC)
struct udevice *dev; /* Device for this MMC controller */
#endif
};
@ -519,7 +519,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
enum mmc_hwpart_conf_mode mode);
#ifndef CONFIG_DM_MMC_OPS
#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
int mmc_getcd(struct mmc *mmc);
int board_mmc_getcd(struct mmc *mmc);
int mmc_getwp(struct mmc *mmc);

View File

@ -23,3 +23,4 @@
#define PALMAS_LDO_VOLT_MAX 3300000
#define PALMAS_LDO_MODE_MASK 0x1
#define PALMAS_LDO_STATUS_MASK 0x10
#define PALMAS_LDO_BYPASS_EN 0x40