summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/core/Kconfig30
-rw-r--r--drivers/core/device.c20
-rw-r--r--drivers/dfu/dfu_sf.c13
-rw-r--r--drivers/dma/keystone_nav.c2
-rw-r--r--drivers/gpio/axp_gpio.c11
-rw-r--r--drivers/gpio/omap_gpio.c11
-rw-r--r--drivers/mmc/Kconfig6
-rw-r--r--drivers/mmc/mv_sdhci.c41
-rw-r--r--drivers/mmc/omap_hsmmc.c124
-rw-r--r--drivers/mmc/s5p_sdhci.c50
-rw-r--r--drivers/net/cpsw.c378
-rw-r--r--drivers/net/keystone_net.c50
-rw-r--r--drivers/pci/pci-uclass.c93
-rw-r--r--drivers/pci/pci_auto.c6
-rw-r--r--drivers/pci/pcie_imx.c8
-rw-r--r--drivers/power/Kconfig208
-rw-r--r--drivers/power/axp152.c40
-rw-r--r--drivers/power/axp209.c117
-rw-r--r--drivers/power/axp221.c41
-rw-r--r--drivers/remoteproc/Kconfig24
-rw-r--r--drivers/remoteproc/Makefile10
-rw-r--r--drivers/remoteproc/rproc-uclass.c417
-rw-r--r--drivers/remoteproc/sandbox_testproc.c336
-rw-r--r--drivers/rtc/mc146818.c6
-rw-r--r--drivers/rtc/rtc-uclass.c2
-rw-r--r--drivers/serial/Kconfig21
-rw-r--r--drivers/serial/ns16550.c2
-rw-r--r--drivers/serial/serial_efi.c2
-rw-r--r--drivers/serial/serial_omap.c8
-rw-r--r--drivers/serial/serial_s5p.c2
-rw-r--r--drivers/spi/ich.c3
-rw-r--r--drivers/usb/gadget/f_fastboot.c2
-rw-r--r--drivers/usb/host/Kconfig7
-rw-r--r--drivers/usb/host/ehci-marvell.c86
-rw-r--r--drivers/video/sunxi_display.c6
-rw-r--r--drivers/video/vesa_fb.c2
38 files changed, 1881 insertions, 307 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 63c92c594a..c02f3231e0 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -46,6 +46,8 @@ source "drivers/power/Kconfig"
source "drivers/ram/Kconfig"
+source "drivers/remoteproc/Kconfig"
+
source "drivers/rtc/Kconfig"
source "drivers/serial/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 9d0a5959a8..1a30ad1d14 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -59,6 +59,7 @@ obj-y += pwm/
obj-y += input/
# SOC specific infrastructure drivers.
obj-y += soc/
+obj-$(CONFIG_REMOTEPROC) += remoteproc/
obj-y += thermal/
endif
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 41f4e695e8..15681df6d3 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -120,4 +120,34 @@ config SPL_SIMPLE_BUS
Supports the 'simple-bus' driver, which is used on some systems
in SPL.
+config OF_TRANSLATE
+ bool "Translate addresses using fdt_translate_address"
+ depends on DM && OF_CONTROL
+ default y
+ help
+ If this option is enabled, the reg property will be translated
+ using the fdt_translate_address() function. This is necessary
+ on some platforms (e.g. MVEBU) using complex "ranges"
+ properties in many nodes. As this translation is not handled
+ correctly in the default simple_bus_translate() function.
+
+ If this option is not enabled, simple_bus_translate() will be
+ used for the address translation. This function is faster and
+ smaller in size than fdt_translate_address().
+
+config SPL_OF_TRANSLATE
+ bool "Translate addresses using fdt_translate_address"
+ depends on SPL_DM && SPL_OF_CONTROL
+ default n
+ help
+ If this option is enabled, the reg property will be translated
+ using the fdt_translate_address() function. This is necessary
+ on some platforms (e.g. MVEBU) using complex "ranges"
+ properties in many nodes. As this translation is not handled
+ correctly in the default simple_bus_translate() function.
+
+ If this option is not enabled, simple_bus_translate() will be
+ used for the address translation. This function is faster and
+ smaller in size than fdt_translate_address().
+
endmenu
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 833a803696..a3dc2ca679 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -11,6 +11,7 @@
#include <common.h>
#include <fdtdec.h>
+#include <fdt_support.h>
#include <malloc.h>
#include <dm/device.h>
#include <dm/device-internal.h>
@@ -585,6 +586,25 @@ fdt_addr_t dev_get_addr(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
fdt_addr_t addr;
+ if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
+ const fdt32_t *reg;
+
+ reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", NULL);
+ if (!reg)
+ return FDT_ADDR_T_NONE;
+
+ /*
+ * Use the full-fledged translate function for complex
+ * bus setups.
+ */
+ return fdt_translate_address((void *)gd->fdt_blob,
+ dev->of_offset, reg);
+ }
+
+ /*
+ * Use the "simple" translate function for less complex
+ * bus setups.
+ */
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev->parent->of_offset,
dev->of_offset, "reg",
diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
index c3d3c3bcd8..7646c6b727 100644
--- a/drivers/dfu/dfu_sf.c
+++ b/drivers/dfu/dfu_sf.c
@@ -23,16 +23,25 @@ static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
return spi_flash_read(dfu->data.sf.dev, offset, *len, buf);
}
+static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
+{
+ return (lldiv((start + offset), dfu->data.sf.dev->sector_size)) *
+ dfu->data.sf.dev->sector_size;
+}
+
static int dfu_write_medium_sf(struct dfu_entity *dfu,
u64 offset, void *buf, long *len)
{
int ret;
- ret = spi_flash_erase(dfu->data.sf.dev, offset, *len);
+ ret = spi_flash_erase(dfu->data.sf.dev,
+ find_sector(dfu, dfu->data.sf.start, offset),
+ dfu->data.sf.dev->sector_size);
if (ret)
return ret;
- ret = spi_flash_write(dfu->data.sf.dev, offset, *len, buf);
+ ret = spi_flash_write(dfu->data.sf.dev, dfu->data.sf.start + offset,
+ *len, buf);
if (ret)
return ret;
diff --git a/drivers/dma/keystone_nav.c b/drivers/dma/keystone_nav.c
index dfca75abdc..5a65b62a39 100644
--- a/drivers/dma/keystone_nav.c
+++ b/drivers/dma/keystone_nav.c
@@ -54,7 +54,7 @@ int _qm_init(struct qm_config *cfg)
qm_cfg = cfg;
qm_cfg->mngr_cfg->link_ram_base0 = qm_cfg->i_lram;
- qm_cfg->mngr_cfg->link_ram_size0 = HDESC_NUM * 8;
+ qm_cfg->mngr_cfg->link_ram_size0 = HDESC_NUM * 8 - 1;
qm_cfg->mngr_cfg->link_ram_base1 = 0;
qm_cfg->mngr_cfg->link_ram_size1 = 0;
qm_cfg->mngr_cfg->link_ram_base2 = 0;
diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c
index 2e97cc39d6..bd2ac892d0 100644
--- a/drivers/gpio/axp_gpio.c
+++ b/drivers/gpio/axp_gpio.c
@@ -10,22 +10,13 @@
#include <asm/arch/gpio.h>
#include <asm/arch/pmic_bus.h>
#include <asm/gpio.h>
+#include <axp_pmic.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/root.h>
#include <errno.h>
-#ifdef CONFIG_AXP152_POWER
-#include <axp152.h>
-#elif defined CONFIG_AXP209_POWER
-#include <axp209.h>
-#elif defined CONFIG_AXP221_POWER
-#include <axp221.h>
-#else
-#error Unknown AXP model
-#endif
-
static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
static u8 axp_get_gpio_ctrl_reg(unsigned pin)
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index cd960dc013..93d18e44a5 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -25,6 +25,7 @@
#include <asm/io.h>
#include <asm/errno.h>
#include <malloc.h>
+#include <dt-bindings/gpio/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -276,12 +277,22 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
+static int omap_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args)
+{
+ desc->offset = args->args[0];
+ desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+ return 0;
+}
+
static const struct dm_gpio_ops gpio_omap_ops = {
.direction_input = omap_gpio_direction_input,
.direction_output = omap_gpio_direction_output,
.get_value = omap_gpio_get_value,
.set_value = omap_gpio_set_value,
.get_function = omap_gpio_get_function,
+ .xlate = omap_gpio_xlate,
};
static int omap_gpio_probe(struct udevice *dev)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 6277f92ef5..ceae7bcaec 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -1,5 +1,11 @@
menu "MMC Host controller Support"
+config MMC
+ bool "Enable MMC support"
+ depends on ARCH_SUNXI
+ help
+ TODO: Move all architectures to use this option
+
config DM_MMC
bool "Enable MMC controllers using Driver Model"
depends on DM
diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c
index 75fa014931..82c695f906 100644
--- a/drivers/mmc/mv_sdhci.c
+++ b/drivers/mmc/mv_sdhci.c
@@ -1,6 +1,41 @@
+/*
+ * Marvell SD Host Controller Interface
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
#include <common.h>
#include <malloc.h>
#include <sdhci.h>
+#include <linux/mbus.h>
+
+#define SDHCI_WINDOW_CTRL(win) (0x4080 + ((win) << 4))
+#define SDHCI_WINDOW_BASE(win) (0x4084 + ((win) << 4))
+
+static void sdhci_mvebu_mbus_config(void __iomem *base)
+{
+ const struct mbus_dram_target_info *dram;
+ int i;
+
+ dram = mvebu_mbus_dram_info();
+
+ for (i = 0; i < 4; i++) {
+ writel(0, base + SDHCI_WINDOW_CTRL(i));
+ writel(0, base + SDHCI_WINDOW_BASE(i));
+ }
+
+ for (i = 0; i < dram->num_cs; i++) {
+ const struct mbus_dram_window *cs = dram->cs + i;
+
+ /* Write size, attributes and target id to control register */
+ writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ base + SDHCI_WINDOW_CTRL(i));
+
+ /* Write base address to base register */
+ writel(cs->base, base + SDHCI_WINDOW_BASE(i));
+ }
+}
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
static struct sdhci_ops mv_ops;
@@ -47,6 +82,12 @@ int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks)
mv_ops.write_b = mv_sdhci_writeb;
host->ops = &mv_ops;
#endif
+
+ if (CONFIG_IS_ENABLED(ARCH_MVEBU)) {
+ /* Configure SDHCI MBUS mbus bridge windows */
+ sdhci_mvebu_mbus_config((void __iomem *)regbase);
+ }
+
if (quirks & SDHCI_QUIRK_REG32_RW)
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
else
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index d7b388f3f4..5038a9f55f 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -31,10 +31,15 @@
#include <twl4030.h>
#include <twl6030.h>
#include <palmas.h>
-#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/mmc_host_def.h>
+#if !defined(CONFIG_SOC_KEYSTONE)
+#include <asm/gpio.h>
#include <asm/arch/sys_proto.h>
+#endif
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
/* simplify defines to OMAP_HSMMC_USE_GPIO */
#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \
@@ -52,9 +57,15 @@ struct omap_hsmmc_data {
struct hsmmc *base_addr;
struct mmc_config cfg;
#ifdef OMAP_HSMMC_USE_GPIO
+#ifdef CONFIG_DM_MMC
+ struct gpio_desc cd_gpio; /* Change Detect GPIO */
+ struct gpio_desc wp_gpio; /* Write Protect GPIO */
+ bool cd_inverted;
+#else
int cd_gpio;
int wp_gpio;
#endif
+#endif
};
/* If we fail after 1 second wait, something is really bad */
@@ -64,7 +75,7 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
unsigned int siz);
-#ifdef OMAP_HSMMC_USE_GPIO
+#if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC)
static int omap_mmc_setup_gpio_in(int gpio, const char *label)
{
int ret;
@@ -600,6 +611,34 @@ static void omap_hsmmc_set_ios(struct mmc *mmc)
}
#ifdef OMAP_HSMMC_USE_GPIO
+#ifdef CONFIG_DM_MMC
+static int omap_hsmmc_getcd(struct mmc *mmc)
+{
+ struct omap_hsmmc_data *priv = mmc->priv;
+ int value;
+
+ value = dm_gpio_get_value(&priv->cd_gpio);
+ /* if no CD return as 1 */
+ if (value < 0)
+ return 1;
+
+ if (priv->cd_inverted)
+ return !value;
+ return value;
+}
+
+static int omap_hsmmc_getwp(struct mmc *mmc)
+{
+ struct omap_hsmmc_data *priv = mmc->priv;
+ int value;
+
+ value = dm_gpio_get_value(&priv->wp_gpio);
+ /* if no WP return as 0 */
+ if (value < 0)
+ return 0;
+ return value;
+}
+#else
static int omap_hsmmc_getcd(struct mmc *mmc)
{
struct omap_hsmmc_data *priv_data = mmc->priv;
@@ -628,6 +667,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc)
return gpio_get_value(wp_gpio);
}
#endif
+#endif
static const struct mmc_ops omap_hsmmc_ops = {
.send_cmd = omap_hsmmc_send_cmd,
@@ -639,6 +679,7 @@ static const struct mmc_ops omap_hsmmc_ops = {
#endif
};
+#ifndef CONFIG_DM_MMC
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio)
{
@@ -662,7 +703,8 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) || \
- defined(CONFIG_AM43XX)) && defined(CONFIG_HSMMC2_8BIT)
+ defined(CONFIG_AM43XX) || defined(CONFIG_SOC_KEYSTONE)) && \
+ defined(CONFIG_HSMMC2_8BIT)
/* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
host_caps_val |= MMC_MODE_8BIT;
#endif
@@ -724,3 +766,79 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
return 0;
}
+#else
+static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
+{
+ struct omap_hsmmc_data *priv = dev_get_priv(dev);
+ const void *fdt = gd->fdt_blob;
+ int node = dev->of_offset;
+ struct mmc_config *cfg;
+ int val;
+
+ priv->base_addr = (struct hsmmc *)dev_get_addr(dev);
+ cfg = &priv->cfg;
+
+ cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ val = fdtdec_get_int(fdt, node, "bus-width", -1);
+ if (val < 0) {
+ printf("error: bus-width property missing\n");
+ return -ENOENT;
+ }
+
+ switch (val) {
+ case 0x8:
+ cfg->host_caps |= MMC_MODE_8BIT;
+ case 0x4:
+ cfg->host_caps |= MMC_MODE_4BIT;
+ break;
+ default:
+ printf("error: invalid bus-width property\n");
+ return -ENOENT;
+ }
+
+ cfg->f_min = 400000;
+ cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+ priv->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
+
+ return 0;
+}
+
+static int omap_hsmmc_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct omap_hsmmc_data *priv = dev_get_priv(dev);
+ struct mmc_config *cfg;
+ struct mmc *mmc;
+
+ cfg = &priv->cfg;
+ cfg->name = "OMAP SD/MMC";
+ cfg->ops = &omap_hsmmc_ops;
+
+ mmc = mmc_create(cfg, priv);
+ if (mmc == NULL)
+ return -1;
+
+ upriv->mmc = mmc;
+
+ return 0;
+}
+
+static const struct udevice_id omap_hsmmc_ids[] = {
+ { .compatible = "ti,omap3-hsmmc" },
+ { .compatible = "ti,omap4-hsmmc" },
+ { .compatible = "ti,am33xx-hsmmc" },
+ { }
+};
+
+U_BOOT_DRIVER(omap_hsmmc) = {
+ .name = "omap_hsmmc",
+ .id = UCLASS_MMC,
+ .of_match = omap_hsmmc_ids,
+ .ofdata_to_platdata = omap_hsmmc_ofdata_to_platdata,
+ .probe = omap_hsmmc_probe,
+ .priv_auto_alloc_size = sizeof(struct omap_hsmmc_data),
+};
+#endif
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 4db51d6488..15ecfee961 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -84,9 +84,9 @@ static int s5p_sdhci_core_init(struct sdhci_host *host)
int s5p_sdhci_init(u32 regbase, int index, int bus_width)
{
- struct sdhci_host *host = malloc(sizeof(struct sdhci_host));
+ struct sdhci_host *host = calloc(1, sizeof(struct sdhci_host));
if (!host) {
- printf("sdhci__host malloc fail!\n");
+ printf("sdhci__host allocation fail!\n");
return 1;
}
host->ioaddr = (void *)regbase;
@@ -101,29 +101,31 @@ struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS];
static int do_sdhci_init(struct sdhci_host *host)
{
- int dev_id, flag;
- int err = 0;
+ int dev_id, flag, ret;
flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
dev_id = host->index + PERIPH_ID_SDMMC0;
if (dm_gpio_is_valid(&host->pwr_gpio)) {
dm_gpio_set_value(&host->pwr_gpio, 1);
- err = exynos_pinmux_config(dev_id, flag);
- if (err) {
+ ret = exynos_pinmux_config(dev_id, flag);
+ if (ret) {
debug("MMC not configured\n");
- return err;
+ return ret;
}
}
if (dm_gpio_is_valid(&host->cd_gpio)) {
- if (dm_gpio_get_value(&host->cd_gpio))
+ ret = dm_gpio_get_value(&host->cd_gpio);
+ if (ret) {
+ debug("no SD card detected (%d)\n", ret);
return -ENODEV;
+ }
- err = exynos_pinmux_config(dev_id, flag);
- if (err) {
+ ret = exynos_pinmux_config(dev_id, flag);
+ if (ret) {
printf("external SD not configured\n");
- return err;
+ return ret;
}
}
@@ -170,7 +172,8 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
static int process_nodes(const void *blob, int node_list[], int count)
{
struct sdhci_host *host;
- int i, node;
+ int i, node, ret;
+ int failed = 0;
debug("%s: count = %d\n", __func__, count);
@@ -182,13 +185,22 @@ static int process_nodes(const void *blob, int node_list[], int count)
host = &sdhci_host[i];
- if (sdhci_get_config(blob, node, host)) {
- printf("%s: failed to decode dev %d\n", __func__, i);
- return -1;
+ ret = sdhci_get_config(blob, node, host);
+ if (ret) {
+ printf("%s: failed to decode dev %d (%d)\n", __func__, i, ret);
+ failed++;
+ continue;
+ }
+
+ ret = do_sdhci_init(host);
+ if (ret) {
+ printf("%s: failed to initialize dev %d (%d)\n", __func__, i, ret);
+ failed++;
}
- do_sdhci_init(host);
}
- return 0;
+
+ /* we only consider it an error when all nodes fail */
+ return (failed == count ? -1 : 0);
}
int exynos_mmc_init(const void *blob)
@@ -200,8 +212,6 @@ int exynos_mmc_init(const void *blob)
COMPAT_SAMSUNG_EXYNOS_MMC, node_list,
SDHCI_MAX_HOSTS);
- process_nodes(blob, node_list, count);
-
- return 0;
+ return process_nodes(blob, node_list, count);
}
#endif
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index fb4d621a88..3dff9df377 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -25,6 +25,9 @@
#include <asm/io.h>
#include <phy.h>
#include <asm/arch/cpu.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
#define BITMASK(bits) (BIT(bits) - 1)
#define PHY_REG_MASK 0x1f
@@ -37,6 +40,23 @@
#define FULLDUPLEXEN BIT(0)
#define MIIEN BIT(15)
+/* reg offset */
+#define CPSW_HOST_PORT_OFFSET 0x108
+#define CPSW_SLAVE0_OFFSET 0x208
+#define CPSW_SLAVE1_OFFSET 0x308
+#define CPSW_SLAVE_SIZE 0x100
+#define CPSW_CPDMA_OFFSET 0x800
+#define CPSW_HW_STATS 0x900
+#define CPSW_STATERAM_OFFSET 0xa00
+#define CPSW_CPTS_OFFSET 0xc00
+#define CPSW_ALE_OFFSET 0xd00
+#define CPSW_SLIVER0_OFFSET 0xd80
+#define CPSW_SLIVER1_OFFSET 0xdc0
+#define CPSW_BD_OFFSET 0x2000
+#define CPSW_MDIO_DIV 0xff
+
+#define AM335X_GMII_SEL_OFFSET 0x630
+
/* DMA Registers */
#define CPDMA_TXCONTROL 0x004
#define CPDMA_RXCONTROL 0x014
@@ -218,7 +238,11 @@ struct cpdma_chan {
(priv)->data.slaves; slave++)
struct cpsw_priv {
+#ifdef CONFIG_DM_ETH
+ struct udevice *dev;
+#else
struct eth_device *dev;
+#endif
struct cpsw_platform_data data;
int host_port;
@@ -522,7 +546,7 @@ static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
return 0;
}
-static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div)
+static void cpsw_mdio_init(const char *name, u32 mdio_base, u32 div)
{
struct mii_dev *bus = mdio_alloc();
@@ -563,8 +587,15 @@ static inline void setbit_and_wait_for_clear32(void *addr)
static void cpsw_set_slave_mac(struct cpsw_slave *slave,
struct cpsw_priv *priv)
{
+#ifdef CONFIG_DM_ETH
+ struct eth_pdata *pdata = dev_get_platdata(priv->dev);
+
+ writel(mac_hi(pdata->enetaddr), &slave->regs->sa_hi);
+ writel(mac_lo(pdata->enetaddr), &slave->regs->sa_lo);
+#else
__raw_writel(mac_hi(priv->dev->enetaddr), &slave->regs->sa_hi);
__raw_writel(mac_lo(priv->dev->enetaddr), &slave->regs->sa_lo);
+#endif
}
static void cpsw_slave_update_link(struct cpsw_slave *slave,
@@ -745,9 +776,8 @@ static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
return 0;
}
-static int cpsw_init(struct eth_device *dev, bd_t *bis)
+static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
{
- struct cpsw_priv *priv = dev->priv;
struct cpsw_slave *slave;
int i, ret;
@@ -772,8 +802,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD);
- cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port,
- ALE_SECURE);
+ cpsw_ale_add_ucast(priv, enetaddr, priv->host_port, ALE_SECURE);
cpsw_ale_add_mcast(priv, net_bcast_ethaddr, 1 << priv->host_port);
for_active_slave(slave, priv)
@@ -857,10 +886,8 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
return 0;
}
-static void cpsw_halt(struct eth_device *dev)
+static void _cpsw_halt(struct cpsw_priv *priv)
{
- struct cpsw_priv *priv = dev->priv;
-
writel(0, priv->dma_regs + CPDMA_TXCONTROL);
writel(0, priv->dma_regs + CPDMA_RXCONTROL);
@@ -870,12 +897,10 @@ static void cpsw_halt(struct eth_device *dev)
/* clear dma state */
setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
- priv->data.control(0);
}
-static int cpsw_send(struct eth_device *dev, void *packet, int length)
+static int _cpsw_send(struct cpsw_priv *priv, void *packet, int length)
{
- struct cpsw_priv *priv = dev->priv;
void *buffer;
int len;
int timeout = CPDMA_TIMEOUT;
@@ -896,20 +921,21 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length)
return cpdma_submit(priv, &priv->tx_chan, packet, length);
}
-static int cpsw_recv(struct eth_device *dev)
+static int _cpsw_recv(struct cpsw_priv *priv, uchar **pkt)
{
- struct cpsw_priv *priv = dev->priv;
void *buffer;
int len;
+ int ret = -EAGAIN;
- while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
- invalidate_dcache_range((unsigned long)buffer,
- (unsigned long)buffer + PKTSIZE_ALIGN);
- net_process_received_packet(buffer, len);
- cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
- }
+ ret = cpdma_process(priv, &priv->rx_chan, &buffer, &len);
+ if (ret < 0)
+ return ret;
- return 0;
+ invalidate_dcache_range((unsigned long)buffer,
+ (unsigned long)buffer + PKTSIZE_ALIGN);
+ *pkt = buffer;
+
+ return len;
}
static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
@@ -923,15 +949,14 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
slave->sliver = regs + data->sliver_reg_ofs;
}
-static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
+static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
{
- struct cpsw_priv *priv = (struct cpsw_priv *)dev->priv;
struct phy_device *phydev;
u32 supported = PHY_GBIT_FEATURES;
phydev = phy_connect(priv->bus,
slave->data->phy_addr,
- dev,
+ priv->dev,
slave->data->phy_if);
if (!phydev)
@@ -946,30 +971,14 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
return 1;
}
-int cpsw_register(struct cpsw_platform_data *data)
+int _cpsw_register(struct cpsw_priv *priv)
{
- struct cpsw_priv *priv;
struct cpsw_slave *slave;
+ struct cpsw_platform_data *data = &priv->data;
void *regs = (void *)data->cpsw_base;
- struct eth_device *dev;
-
- dev = calloc(sizeof(*dev), 1);
- if (!dev)
- return -ENOMEM;
-
- priv = calloc(sizeof(*priv), 1);
- if (!priv) {
- free(dev);
- return -ENOMEM;
- }
-
- priv->data = *data;
- priv->dev = dev;
priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
if (!priv->slaves) {
- free(dev);
- free(priv);
return -ENOMEM;
}
@@ -987,6 +996,71 @@ int cpsw_register(struct cpsw_platform_data *data)
idx = idx + 1;
}
+ cpsw_mdio_init(priv->dev->name, data->mdio_base, data->mdio_div);
+ priv->bus = miiphy_get_dev_by_name(priv->dev->name);
+ for_active_slave(slave, priv)
+ cpsw_phy_init(priv, slave);
+
+ return 0;
+}
+
+#ifndef CONFIG_DM_ETH
+static int cpsw_init(struct eth_device *dev, bd_t *bis)
+{
+ struct cpsw_priv *priv = dev->priv;
+
+ return _cpsw_init(priv, dev->enetaddr);
+}
+
+static void cpsw_halt(struct eth_device *dev)
+{
+ struct cpsw_priv *priv = dev->priv;
+
+ return _cpsw_halt(priv);
+}
+
+static int cpsw_send(struct eth_device *dev, void *packet, int length)
+{
+ struct cpsw_priv *priv = dev->priv;
+
+ return _cpsw_send(priv, packet, length);
+}
+
+static int cpsw_recv(struct eth_device *dev)
+{
+ struct cpsw_priv *priv = dev->priv;
+ uchar *pkt = NULL;
+ int len;
+
+ len = _cpsw_recv(priv, &pkt);
+
+ if (len > 0) {
+ net_process_received_packet(pkt, len);
+ cpdma_submit(priv, &priv->rx_chan, pkt, PKTSIZE);
+ }
+
+ return len;
+}
+
+int cpsw_register(struct cpsw_platform_data *data)
+{
+ struct cpsw_priv *priv;
+ struct eth_device *dev;
+ int ret;
+
+ dev = calloc(sizeof(*dev), 1);
+ if (!dev)
+ return -ENOMEM;
+
+ priv = calloc(sizeof(*priv), 1);
+ if (!priv) {
+ free(dev);
+ return -ENOMEM;
+ }
+
+ priv->dev = dev;
+ priv->data = *data;
+
strcpy(dev->name, "cpsw");
dev->iobase = 0;
dev->init = cpsw_init;
@@ -997,10 +1071,224 @@ int cpsw_register(struct cpsw_platform_data *data)
eth_register(dev);
- cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div);
- priv->bus = miiphy_get_dev_by_name(dev->name);
- for_active_slave(slave, priv)
- cpsw_phy_init(dev, slave);
+ ret = _cpsw_register(priv);
+ if (ret < 0) {
+ eth_unregister(dev);
+ free(dev);
+ free(priv);
+ return ret;
+ }
return 1;
}
+#else
+static int cpsw_eth_start(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct cpsw_priv *priv = dev_get_priv(dev);
+
+ return _cpsw_init(priv, pdata->enetaddr);
+}
+
+static int cpsw_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct cpsw_priv *priv = dev_get_priv(dev);
+
+ return _cpsw_send(priv, packet, length);
+}
+
+static int cpsw_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct cpsw_priv *priv = dev_get_priv(dev);
+
+ return _cpsw_recv(priv, packetp);
+}
+
+static int cpsw_eth_free_pkt(struct udevice *dev, uchar *packet,
+ int length)
+{
+ struct cpsw_priv *priv = dev_get_priv(dev);
+
+ return cpdma_submit(priv, &priv->rx_chan, packet, PKTSIZE);
+}
+
+static void cpsw_eth_stop(struct udevice *dev)
+{
+ struct cpsw_priv *priv = dev_get_priv(dev);
+
+ return _cpsw_halt(priv);
+}
+
+
+static int cpsw_eth_probe(struct udevice *dev)
+{
+ struct cpsw_priv *priv = dev_get_priv(dev);
+
+ priv->dev = dev;
+
+ return _cpsw_register(priv);
+}
+
+static const struct eth_ops cpsw_eth_ops = {
+ .start = cpsw_eth_start,
+ .send = cpsw_eth_send,
+ .recv = cpsw_eth_recv,
+ .free_pkt = cpsw_eth_free_pkt,
+ .stop = cpsw_eth_stop,
+};
+
+static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct cpsw_priv *priv = dev_get_priv(dev);
+ const char *phy_mode;
+ const void *fdt = gd->fdt_blob;
+ int node = dev->of_offset;
+ int subnode;
+ int slave_index = 0;
+ uint32_t mac_hi, mac_lo;
+ fdt32_t gmii = 0;
+ int active_slave;
+
+ pdata->iobase = dev_get_addr(dev);
+ priv->data.version = CPSW_CTRL_VERSION_2;
+ priv->data.bd_ram_ofs = CPSW_BD_OFFSET;
+ priv->data.ale_reg_ofs = CPSW_ALE_OFFSET;
+ priv->data.cpdma_reg_ofs = CPSW_CPDMA_OFFSET;
+ priv->data.mdio_div = CPSW_MDIO_DIV;
+ priv->data.host_port_reg_ofs = CPSW_HOST_PORT_OFFSET,
+
+ pdata->phy_interface = -1;
+
+ priv->data.cpsw_base = pdata->iobase;
+ priv->data.channels = fdtdec_get_int(fdt, node, "cpdma_channels", -1);
+ if (priv->data.channels <= 0) {
+ printf("error: cpdma_channels not found in dt\n");
+ return -ENOENT;
+ }
+
+ priv->data.slaves = fdtdec_get_int(fdt, node, "slaves", -1);
+ if (priv->data.slaves <= 0) {
+ printf("error: slaves not found in dt\n");
+ return -ENOENT;
+ }
+ priv->data.slave_data = malloc(sizeof(struct cpsw_slave_data) *
+ priv->data.slaves);
+
+ priv->data.ale_entries = fdtdec_get_int(fdt, node, "ale_entries", -1);
+ if (priv->data.ale_entries <= 0) {
+ printf("error: ale_entries not found in dt\n");
+ return -ENOENT;
+ }
+
+ priv->data.bd_ram_ofs = fdtdec_get_int(fdt, node, "bd_ram_size", -1);
+ if (priv->data.bd_ram_ofs <= 0) {
+ printf("error: bd_ram_size not found in dt\n");
+ return -ENOENT;
+ }
+
+ priv->data.mac_control = fdtdec_get_int(fdt, node, "mac_control", -1);
+ if (priv->data.mac_control <= 0) {
+ printf("error: ale_entries not found in dt\n");
+ return -ENOENT;
+ }
+
+ active_slave = fdtdec_get_int(fdt, node, "active_slave", 0);
+ priv->data.active_slave = active_slave;
+
+ fdt_for_each_subnode(fdt, subnode, node) {
+ int len;
+ const char *name;
+
+ name = fdt_get_name(fdt, subnode, &len);
+ if (!strncmp(name, "mdio", 4)) {
+ priv->data.mdio_base = fdtdec_get_addr(fdt, subnode,
+ "reg");
+ }
+
+ if (!strncmp(name, "slave", 5)) {
+ u32 phy_id[2];
+
+ if (slave_index >= priv->data.slaves) {
+ printf("error: num slaves and slave nodes did not match\n");
+ return -EINVAL;
+ }
+ phy_mode = fdt_getprop(fdt, subnode, "phy-mode", NULL);
+ if (phy_mode)
+ priv->data.slave_data[slave_index].phy_if =
+ phy_get_interface_by_name(phy_mode);
+ fdtdec_get_int_array(fdt, subnode, "phy_id", phy_id, 2);
+ priv->data.slave_data[slave_index].phy_addr = phy_id[1];
+ slave_index++;
+ }
+
+ if (!strncmp(name, "cpsw-phy-sel", 12)) {
+ priv->data.gmii_sel = fdtdec_get_addr(fdt, subnode,
+ "reg");
+ }
+ }
+
+ priv->data.slave_data[0].slave_reg_ofs = CPSW_SLAVE0_OFFSET;
+ priv->data.slave_data[0].sliver_reg_ofs = CPSW_SLIVER0_OFFSET;
+
+ if (priv->data.slaves == 2) {
+ priv->data.slave_data[1].slave_reg_ofs = CPSW_SLAVE1_OFFSET;
+ priv->data.slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET;
+ }
+
+ subnode = fdtdec_lookup_phandle(fdt, node, "syscon");
+ priv->data.mac_id = fdt_translate_address((void *)fdt, subnode, &gmii);
+ priv->data.mac_id += AM335X_GMII_SEL_OFFSET;
+ priv->data.mac_id += active_slave * 8;
+
+ /* try reading mac address from efuse */
+ mac_lo = readl(priv->data.mac_id);
+ mac_hi = readl(priv->data.mac_id + 4);
+ pdata->enetaddr[0] = mac_hi & 0xFF;
+ pdata->enetaddr[1] = (mac_hi & 0xFF00) >> 8;
+ pdata->enetaddr[2] = (mac_hi & 0xFF0000) >> 16;
+ pdata->enetaddr[3] = (mac_hi & 0xFF000000) >> 24;
+ pdata->enetaddr[4] = mac_lo & 0xFF;
+ pdata->enetaddr[5] = (mac_lo & 0xFF00) >> 8;
+
+ pdata->phy_interface = priv->data.slave_data[active_slave].phy_if;
+ if (pdata->phy_interface == -1) {
+ debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ return -EINVAL;
+ }
+ switch (pdata->phy_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ writel(MII_MODE_ENABLE, priv->data.gmii_sel);
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ writel(RMII_MODE_ENABLE, priv->data.gmii_sel);
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ writel(RGMII_MODE_ENABLE, priv->data.gmii_sel);
+ break;
+ }
+ return 0;
+}
+
+
+static const struct udevice_id cpsw_eth_ids[] = {
+ { .compatible = "ti,cpsw" },
+ { .compatible = "ti,am335x-cpsw" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_cpsw) = {
+ .name = "eth_cpsw",
+ .id = UCLASS_ETH,
+ .of_match = cpsw_eth_ids,
+ .ofdata_to_platdata = cpsw_eth_ofdata_to_platdata,
+ .probe = cpsw_eth_probe,
+ .ops = &cpsw_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct cpsw_priv),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif /* CONFIG_DM_ETH */
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index 67b570279e..5ed29ae917 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -42,7 +42,9 @@ struct rx_buff_desc net_rx_buffs = {
.rx_flow = 22,
};
+#ifndef CONFIG_SOC_K2G
static void keystone2_net_serdes_setup(void);
+#endif
int keystone2_eth_read_mac_addr(struct eth_device *dev)
{
@@ -161,16 +163,37 @@ static void __attribute__((unused))
DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL);
}
-int keystone_sgmii_link_status(int port)
+#ifdef CONFIG_SOC_K2G
+int keystone_rgmii_config(struct phy_device *phy_dev)
{
- u32 status = 0;
+ unsigned int i, status;
- status = __raw_readl(SGMII_STATUS_REG(port));
+ i = 0;
+ do {
+ if (i > SGMII_ANEG_TIMEOUT) {
+ puts(" TIMEOUT !\n");
+ phy_dev->link = 0;
+ return 0;
+ }
- return (status & SGMII_REG_STATUS_LOCK) &&
- (status & SGMII_REG_STATUS_LINK);
-}
+ if (ctrlc()) {
+ puts("user interrupt!\n");
+ phy_dev->link = 0;
+ return -EINTR;
+ }
+ if ((i++ % 500) == 0)
+ printf(".");
+
+ udelay(1000); /* 1 ms */
+ status = readl(RGMII_STATUS_REG);
+ } while (!(status & RGMII_REG_STATUS_LINK));
+
+ puts(" done\n");
+
+ return 0;
+}
+#else
int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface)
{
unsigned int i, status, mask;
@@ -264,6 +287,7 @@ int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface)
return 0;
}
+#endif
int mac_sl_reset(u32 port)
{
@@ -315,7 +339,7 @@ int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN);
writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL);
-#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L)
+#ifndef CONFIG_SOC_K2HK
/* Map RX packet flow priority to 0 */
writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP);
#endif
@@ -401,8 +425,12 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
if (sys_has_mdio)
keystone2_mdio_reset(mdio_bus);
+#ifdef CONFIG_SOC_K2G
+ keystone_rgmii_config(phy_dev);
+#else
keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1,
eth_priv->sgmii_link_type);
+#endif
udelay(10000);
@@ -564,16 +592,18 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
return res;
}
+#ifndef CONFIG_SOC_K2G
keystone2_net_serdes_setup();
+#endif
/* Create phy device and bind it with driver */
#ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
- dev, PHY_INTERFACE_MODE_SGMII);
+ dev, eth_priv->phy_if);
phy_config(phy_dev);
#else
phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr,
- PHY_INTERFACE_MODE_SGMII);
+ eth_priv->phy_if);
phy_dev->dev = dev;
#endif
eth_priv->phy_dev = phy_dev;
@@ -589,6 +619,7 @@ struct ks2_serdes ks2_serdes_sgmii_156p25mhz = {
.loopback = 0,
};
+#ifndef CONFIG_SOC_K2G
static void keystone2_net_serdes_setup(void)
{
ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE,
@@ -604,3 +635,4 @@ static void keystone2_net_serdes_setup(void)
/* wait till setup */
udelay(5000);
}
+#endif
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 0756bbe8f1..1d93194b67 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -85,30 +85,7 @@ static int pci_get_bus_max(void)
int pci_last_busno(void)
{
- struct pci_controller *hose;
- struct udevice *bus;
- struct uclass *uc;
- int ret;
-
- debug("pci_last_busno\n");
- ret = uclass_get(UCLASS_PCI, &uc);
- if (ret || list_empty(&uc->dev_head))
- return -1;
-
- /* Probe the last bus */
- bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
- debug("bus = %p, %s\n", bus, bus->name);
- assert(bus);
- ret = device_probe(bus);
- if (ret)
- return ret;
-
- /* If that bus has bridges, we may have new buses now. Get the last */
- bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
- hose = dev_get_uclass_priv(bus);
- debug("bus = %s, hose = %p\n", bus->name, hose);
-
- return hose->last_busno;
+ return pci_get_bus_max();
}
int pci_get_ff(enum pci_size_t size)
@@ -387,9 +364,23 @@ int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep)
return 0;
}
+static void set_vga_bridge_bits(struct udevice *dev)
+{
+ struct udevice *parent = dev->parent;
+ u16 bc;
+
+ while (parent->seq != 0) {
+ dm_pci_read_config16(parent, PCI_BRIDGE_CONTROL, &bc);
+ bc |= PCI_BRIDGE_CTL_VGA;
+ dm_pci_write_config16(parent, PCI_BRIDGE_CONTROL, bc);
+ parent = parent->parent;
+ }
+}
+
int pci_auto_config_devices(struct udevice *bus)
{
struct pci_controller *hose = bus->uclass_priv;
+ struct pci_child_platdata *pplat;
unsigned int sub_bus;
struct udevice *dev;
int ret;
@@ -401,10 +392,18 @@ int pci_auto_config_devices(struct udevice *bus)
!ret && dev;
ret = device_find_next_child(&dev)) {
unsigned int max_bus;
+ int ret;
debug("%s: device %s\n", __func__, dev->name);
- max_bus = pciauto_config_device(hose, pci_get_bdf(dev));
+ ret = pciauto_config_device(hose, pci_get_bdf(dev));
+ if (ret < 0)
+ return ret;
+ max_bus = ret;
sub_bus = max(sub_bus, max_bus);
+
+ pplat = dev_get_parent_platdata(dev);
+ if (pplat->class == (PCI_CLASS_DISPLAY_VGA << 8))
+ set_vga_bridge_bits(dev);
}
debug("%s: done\n", __func__);
@@ -434,7 +433,7 @@ int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
ret = device_probe(bus);
if (ret) {
- debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name,
+ debug("%s: Cannot probe bus %s: %d\n", __func__, bus->name,
ret);
return ret;
}
@@ -474,10 +473,17 @@ static bool pci_match_one_id(const struct pci_device_id *id,
* pci_find_and_bind_driver() - Find and bind the right PCI driver
*
* This only looks at certain fields in the descriptor.
+ *
+ * @parent: Parent bus
+ * @find_id: Specification of the driver to find
+ * @bdf: Bus/device/function addreess - see PCI_BDF()
+ * @devp: Returns a pointer to the device created
+ * @return 0 if OK, -EPERM if the device is not needed before relocation and
+ * therefore was not created, other -ve value on error
*/
static int pci_find_and_bind_driver(struct udevice *parent,
- struct pci_device_id *find_id, pci_dev_t bdf,
- struct udevice **devp)
+ struct pci_device_id *find_id,
+ pci_dev_t bdf, struct udevice **devp)
{
struct pci_driver_entry *start, *entry;
const char *drv;
@@ -513,7 +519,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
*/
if (!(gd->flags & GD_FLG_RELOC) &&
!(drv->flags & DM_FLAG_PRE_RELOC))
- return 0;
+ return -EPERM;
/*
* We could pass the descriptor to the driver as
@@ -541,7 +547,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
* limited (ie: using Cache As RAM).
*/
if (!(gd->flags & GD_FLG_RELOC) && !bridge)
- return 0;
+ return -EPERM;
/* Bind a generic driver so that the device can be used */
sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
@@ -553,7 +559,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
ret = device_bind_driver(parent, drv, str, devp);
if (ret) {
- debug("%s: Failed to bind generic driver: %d", __func__, ret);
+ debug("%s: Failed to bind generic driver: %d\n", __func__, ret);
return ret;
}
debug("%s: No match found: bound generic driver instead\n", __func__);
@@ -629,17 +635,17 @@ int pci_bind_bus_devices(struct udevice *bus)
ret = pci_find_and_bind_driver(bus, &find_id, bdf,
&dev);
}
- if (ret)
+ if (ret == -EPERM)
+ continue;
+ else if (ret)
return ret;
/* Update the platform data */
- if (dev) {
- pplat = dev_get_parent_platdata(dev);
- pplat->devfn = PCI_MASK_BUS(bdf);
- pplat->vendor = vendor;
- pplat->device = device;
- pplat->class = class;
- }
+ pplat = dev_get_parent_platdata(dev);
+ pplat->devfn = PCI_MASK_BUS(bdf);
+ pplat->vendor = vendor;
+ pplat->device = device;
+ pplat->class = class;
}
return 0;
@@ -777,6 +783,8 @@ static int pci_uclass_post_probe(struct udevice *bus)
#ifdef CONFIG_PCI_PNP
ret = pci_auto_config_devices(bus);
+ if (ret < 0)
+ return ret;
#endif
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
@@ -793,11 +801,14 @@ static int pci_uclass_post_probe(struct udevice *bus)
* Note we only call this 1) after U-Boot is relocated, and 2)
* root bus has finished probing.
*/
- if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0))
+ if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0)) {
ret = fsp_init_phase_pci();
+ if (ret)
+ return ret;
+ }
#endif
- return ret < 0 ? ret : 0;
+ return 0;
}
static int pci_uclass_child_post_bind(struct udevice *dev)
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 79f27c744b..0412bf3515 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -89,6 +89,7 @@ void pciauto_setup_device(struct pci_controller *hose,
struct pci_region *bar_res;
int found_mem64 = 0;
#endif
+ u16 class;
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
@@ -206,6 +207,11 @@ void pciauto_setup_device(struct pci_controller *hose,
}
#endif
+ /* PCI_COMMAND_IO must be set for VGA device */
+ pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+ if (class == PCI_CLASS_DISPLAY_VGA)
+ cmdstat |= PCI_COMMAND_IO;
+
pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat);
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE,
CONFIG_SYS_PCI_CACHE_LINE_SIZE);
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c
index 1568f20c1a..f1e189edd5 100644
--- a/drivers/pci/pcie_imx.c
+++ b/drivers/pci/pcie_imx.c
@@ -19,6 +19,7 @@
#include <asm/io.h>
#include <linux/sizes.h>
#include <errno.h>
+#include <asm/arch/sys_proto.h>
#define PCI_ACCESS_READ 0
#define PCI_ACCESS_WRITE 1
@@ -430,6 +431,10 @@ static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
static int imx6_pcie_assert_core_reset(void)
{
struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+ if (is_mx6dqp())
+ setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
+
#if defined(CONFIG_MX6SX)
struct gpc *gpc_regs = (struct gpc *)GPC_BASE_ADDR;
@@ -536,6 +541,9 @@ static int imx6_pcie_deassert_core_reset(void)
enable_pcie_clock();
+ if (is_mx6dqp())
+ clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
+
/*
* Wait for the clock to settle a bit, when the clock are sourced
* from the CPU, we need about 30 ms to settle.
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index df5e3734b0..809f8f1180 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -4,87 +4,201 @@ source "drivers/power/pmic/Kconfig"
source "drivers/power/regulator/Kconfig"
+choice
+ prompt "Select Sunxi PMIC Variant"
+ depends on ARCH_SUNXI
+ default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
+ default AXP221_POWER if MACH_SUN6I || MACH_SUN8I
+
+config SUNXI_NO_PMIC
+ boolean "board without a pmic"
+ ---help---
+ Select this for boards which do not use a PMIC.
+
+config AXP152_POWER
+ boolean "axp152 pmic support"
+ depends on MACH_SUN5I
+ ---help---
+ Select this to enable support for the axp152 pmic found on most
+ A10s boards.
+
+config AXP209_POWER
+ boolean "axp209 pmic support"
+ depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
+ ---help---
+ Select this to enable support for the axp209 pmic found on most
+ A10, A13 and A20 boards.
+
config AXP221_POWER
boolean "axp221 / axp223 pmic support"
depends on MACH_SUN6I || MACH_SUN8I
- default y
---help---
- Say y here to enable support for the axp221 / axp223 pmic found on most
- sun6i (A31) / sun8i (A23) boards.
+ Select this to enable support for the axp221/axp223 pmic found on most
+ A23 and A31 boards.
+
+endchoice
+
+config AXP_DCDC1_VOLT
+ int "axp pmic dcdc1 voltage"
+ depends on AXP221_POWER
+ default 3000 if MACH_SUN6I || MACH_SUN8I
+ ---help---
+ Set the voltage (mV) to program the axp pmic dcdc1 at, set to 0 to
+ disable dcdc1. On A23 / A31 / A33 (axp221) boards dcdc1 is used for
+ generic 3.3V IO voltage for external devices like the lcd-panal and
+ sdcard interfaces, etc. On most boards dcdc1 is undervolted to 3.0V to
+ safe battery. On A31 devices dcdc1 is also used for VCC-IO.
-config AXP221_DCDC1_VOLT
- int "axp221 dcdc1 voltage"
+config AXP_DCDC2_VOLT
+ int "axp pmic dcdc2 voltage"
+ depends on AXP152_POWER || AXP209_POWER || AXP221_POWER
+ default 1400 if AXP152_POWER || AXP209_POWER
+ default 1200 if MACH_SUN6I
+ default 1100 if MACH_SUN8I
+ ---help---
+ Set the voltage (mV) to program the axp pmic dcdc2 at, set to 0 to
+ disable dcdc2.
+ On A10(s) / A13 / A20 boards dcdc2 is VDD-CPU and should be 1.4V.
+ On A31 boards dcdc2 is used for VDD-GPU and should be 1.2V.
+ On A23/A33 boards dcdc2 is used for VDD-SYS and should be 1.1V.
+
+config AXP_DCDC3_VOLT
+ int "axp pmic dcdc3 voltage"
+ depends on AXP152_POWER || AXP209_POWER || AXP221_POWER
+ default 1500 if AXP152_POWER
+ default 1250 if AXP209_POWER
+ default 1200 if MACH_SUN6I || MACH_SUN8I
+ ---help---
+ Set the voltage (mV) to program the axp pmic dcdc3 at, set to 0 to
+ disable dcdc3.
+ On A10(s) / A13 / A20 boards with an axp209 dcdc3 is VDD-INT-DLL and
+ should be 1.25V.
+ On A10s boards with an axp152 dcdc3 is VCC-DRAM and should be 1.5V.
+ On A23 / A31 / A33 boards dcdc3 is VDD-CPU and should be 1.2V.
+
+config AXP_DCDC4_VOLT
+ int "axp pmic dcdc4 voltage"
+ depends on AXP152_POWER || AXP221_POWER
+ default 1250 if AXP152_POWER
+ default 1200 if MACH_SUN6I
+ default 0 if MACH_SUN8I
+ ---help---
+ Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to
+ disable dcdc4.
+ On A10s boards with an axp152 dcdc4 is VDD-INT-DLL and should be 1.25V.
+ On A31 boards dcdc4 is used for VDD-SYS and should be 1.2V.
+ On A23 / A33 boards dcdc4 is unused and should be disabled.
+
+config AXP_DCDC5_VOLT
+ int "axp pmic dcdc5 voltage"
depends on AXP221_POWER
- default 3000
+ default 1500 if MACH_SUN6I || MACH_SUN8I
---help---
- Set the voltage (mV) to program the axp221 dcdc1 at, set to 0 to
- disable dcdc1. This is typically used as generic 3.3V IO voltage for
- things like GPIO-s, sdcard interfaces, etc. On most boards this is
- undervolted to 3.0V to safe battery.
+ Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to
+ disable dcdc5.
+ On A23 / A31 / A33 boards dcdc5 is VCC-DRAM and should be 1.5V.
-config AXP221_DCDC2_VOLT
- int "axp221 dcdc2 voltage"
+config AXP_ALDO1_VOLT
+ int "axp pmic (a)ldo1 voltage"
depends on AXP221_POWER
- default 1200
+ default 0 if MACH_SUN6I
+ default 3000 if MACH_SUN8I
---help---
- Set the voltage (mV) to program the axp221 dcdc2 at, set to 0 to
- disable dcdc2. On A31 boards this is typically used for VDD-GPU,
- on A23/A33 for VDD-SYS, this should normally be set to 1.2V.
+ Set the voltage (mV) to program the axp pmic aldo1 at, set to 0 to
+ disable aldo1.
+ On A31 boards aldo1 is often used to power the wifi module.
+ On A23 / A33 boards aldo1 is used for VCC-IO and should be 3.0V.
-config AXP221_DLDO1_VOLT
- int "axp221 dldo1 voltage"
+config AXP_ALDO2_VOLT
+ int "axp pmic (a)ldo2 voltage"
+ depends on AXP152_POWER || AXP209_POWER || AXP221_POWER
+ default 3000 if AXP152_POWER || AXP209_POWER
+ default 0 if MACH_SUN6I
+ default 2500 if MACH_SUN8I
+ ---help---
+ Set the voltage (mV) to program the axp pmic aldo2 at, set to 0 to
+ disable aldo2.
+ On A10(s) / A13 / A20 boards aldo2 is AVCC and should be 3.0V.
+ On A31 boards aldo2 is typically unused and should be disabled.
+ On A31 boards aldo2 may be used for LPDDR2 then it should be 1.8V.
+ On A23 / A33 boards aldo2 is used for VDD-DLL and should be 2.5V.
+
+config AXP_ALDO3_VOLT
+ int "axp pmic (a)ldo3 voltage"
+ depends on AXP209_POWER || AXP221_POWER
+ default 0 if AXP209_POWER
+ default 3000 if MACH_SUN6I || MACH_SUN8I
+ ---help---
+ Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to
+ disable aldo3.
+ On A10(s) / A13 / A20 boards aldo3 should be 2.8V.
+ On A23 / A31 / A33 boards aldo3 is VCC-PLL and AVCC and should be 3.0V.
+
+config AXP_ALDO4_VOLT
+ int "axp pmic (a)ldo4 voltage"
+ depends on AXP209_POWER
+ default 0 if AXP209_POWER
+ ---help---
+ Set the voltage (mV) to program the axp pmic aldo4 at, set to 0 to
+ disable aldo4.
+ On A10(s) / A13 / A20 boards aldo4 should be 2.8V.
+
+config AXP_DLDO1_VOLT
+ int "axp pmic dldo1 voltage"
depends on AXP221_POWER
default 0
---help---
- Set the voltage (mV) to program the axp221 dldo1 at, set to 0 to
- disable dldo1. On sun6i (A31) boards with ethernet this is often used
+ Set the voltage (mV) to program the axp pmic dldo1 at, set to 0 to
+ disable dldo1. On sun6i (A31) boards with ethernet dldo1 is often used
to power the ethernet phy. On sun8i (A23) boards this is often used to
power the wifi.
-config AXP221_DLDO4_VOLT
- int "axp221 dldo4 voltage"
+config AXP_DLDO2_VOLT
+ int "axp pmic dldo2 voltage"
depends on AXP221_POWER
default 0
---help---
- Set the voltage (mV) to program the axp221 dldo4 at, set to 0 to
- disable dldo4.
+ Set the voltage (mV) to program the axp pmic dldo2 at, set to 0 to
+ disable dldo2.
-config AXP221_ALDO1_VOLT
- int "axp221 aldo1 voltage"
+config AXP_DLDO3_VOLT
+ int "axp pmic dldo3 voltage"
depends on AXP221_POWER
default 0
---help---
- Set the voltage (mV) to program the axp221 aldo1 at, set to 0 to
- disable aldo1. On sun6i (A31) boards which have a wifi module this is
- often used to power the wifi module.
+ Set the voltage (mV) to program the axp pmic dldo3 at, set to 0 to
+ disable dldo3.
-config AXP221_ALDO2_VOLT
- int "axp221 aldo2 voltage"
+config AXP_DLDO4_VOLT
+ int "axp pmic dldo4 voltage"
depends on AXP221_POWER
- default 0 if MACH_SUN6I
- default 2500 if MACH_SUN8I
+ default 0
---help---
- Set the voltage (mV) to program the axp221 aldo2 at, set to 0 to
- disable aldo2. On sun6i (A31) boards this is typically unused and
- should be disabled, if it is used for LPDDR2 it should be set to 1.8V.
- On sun8i (A23) this is typically connected to VDD-DLL and must be set
- to 2.5V.
+ Set the voltage (mV) to program the axp pmic dldo4 at, set to 0 to
+ disable dldo4.
-config AXP221_ALDO3_VOLT
- int "axp221 aldo3 voltage"
+config AXP_ELDO1_VOLT
+ int "axp pmic eldo1 voltage"
depends on AXP221_POWER
- default 3000
+ default 0
+ ---help---
+ Set the voltage (mV) to program the axp pmic eldo1 at, set to 0 to
+ disable eldo1.
+
+config AXP_ELDO2_VOLT
+ int "axp pmic eldo2 voltage"
+ depends on AXP221_POWER
+ default 0
---help---
- Set the voltage (mV) to program the axp221 aldo3 at, set to 0 to
- disable aldo3. This is typically connected to VCC-PLL and AVCC and
- must be set to 3V.
+ Set the voltage (mV) to program the axp pmic eldo2 at, set to 0 to
+ disable eldo2.
-config AXP221_ELDO3_VOLT
- int "axp221 eldo3 voltage"
+config AXP_ELDO3_VOLT
+ int "axp pmic eldo3 voltage"
depends on AXP221_POWER
default 0
---help---
- Set the voltage (mV) to program the axp221 eldo3 at, set to 0 to
+ Set the voltage (mV) to program the axp pmic eldo3 at, set to 0 to
disable eldo3. On some A31(s) tablets it might be used to supply
1.2V for the SSD2828 chip (converter of parallel LCD interface
into MIPI DSI).
diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c
index 740a3b41cd..297258692d 100644
--- a/drivers/power/axp152.c
+++ b/drivers/power/axp152.c
@@ -5,18 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
-#include <i2c.h>
-#include <axp152.h>
-
-static int axp152_write(enum axp152_reg reg, u8 val)
-{
- return i2c_write(0x30, reg, 1, &val, 1);
-}
-
-static int axp152_read(enum axp152_reg reg, u8 *val)
-{
- return i2c_read(0x30, reg, 1, val, 1);
-}
+#include <asm/arch/pmic_bus.h>
+#include <axp_pmic.h>
static u8 axp152_mvolt_to_target(int mvolt, int min, int max, int div)
{
@@ -28,7 +18,7 @@ static u8 axp152_mvolt_to_target(int mvolt, int min, int max, int div)
return (mvolt - min) / div;
}
-int axp152_set_dcdc2(int mvolt)
+int axp_set_dcdc2(unsigned int mvolt)
{
int rc;
u8 current, target;
@@ -36,46 +26,50 @@ int axp152_set_dcdc2(int mvolt)
target = axp152_mvolt_to_target(mvolt, 700, 2275, 25);
/* Do we really need to be this gentle? It has built-in voltage slope */
- while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, &current)) == 0 &&
+ while ((rc = pmic_bus_read(AXP152_DCDC2_VOLTAGE, &current)) == 0 &&
current != target) {
if (current < target)
current++;
else
current--;
- rc = axp152_write(AXP152_DCDC2_VOLTAGE, current);
+ rc = pmic_bus_write(AXP152_DCDC2_VOLTAGE, current);
if (rc)
break;
}
return rc;
}
-int axp152_set_dcdc3(int mvolt)
+int axp_set_dcdc3(unsigned int mvolt)
{
u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 50);
- return axp152_write(AXP152_DCDC3_VOLTAGE, target);
+ return pmic_bus_write(AXP152_DCDC3_VOLTAGE, target);
}
-int axp152_set_dcdc4(int mvolt)
+int axp_set_dcdc4(unsigned int mvolt)
{
u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 25);
- return axp152_write(AXP152_DCDC4_VOLTAGE, target);
+ return pmic_bus_write(AXP152_DCDC4_VOLTAGE, target);
}
-int axp152_set_ldo2(int mvolt)
+int axp_set_aldo2(unsigned int mvolt)
{
u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 100);
- return axp152_write(AXP152_LDO2_VOLTAGE, target);
+ return pmic_bus_write(AXP152_LDO2_VOLTAGE, target);
}
-int axp152_init(void)
+int axp_init(void)
{
u8 ver;
int rc;
- rc = axp152_read(AXP152_CHIP_VERSION, &ver);
+ rc = pmic_bus_init();
+ if (rc)
+ return rc;
+
+ rc = pmic_bus_read(AXP152_CHIP_VERSION, &ver);
if (rc)
return rc;
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index 5161bc1472..71aa000daa 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -6,19 +6,8 @@
*/
#include <common.h>
-#include <i2c.h>
-#include <asm/arch/gpio.h>
-#include <axp209.h>
-
-static int axp209_write(enum axp209_reg reg, u8 val)
-{
- return i2c_write(0x34, reg, 1, &val, 1);
-}
-
-static int axp209_read(enum axp209_reg reg, u8 *val)
-{
- return i2c_read(0x34, reg, 1, val, 1);
-}
+#include <asm/arch/pmic_bus.h>
+#include <axp_pmic.h>
static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
{
@@ -30,22 +19,30 @@ static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
return (mvolt - min) / div;
}
-int axp209_set_dcdc2(int mvolt)
+int axp_set_dcdc2(unsigned int mvolt)
{
int rc;
u8 cfg, current;
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
+ AXP209_OUTPUT_CTRL_DCDC2);
+
+ rc = pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_DCDC2);
+ if (rc)
+ return rc;
+
cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25);
/* Do we really need to be this gentle? It has built-in voltage slope */
- while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, &current)) == 0 &&
+ while ((rc = pmic_bus_read(AXP209_DCDC2_VOLTAGE, &current)) == 0 &&
current != cfg) {
if (current < cfg)
current++;
else
current--;
- rc = axp209_write(AXP209_DCDC2_VOLTAGE, current);
+ rc = pmic_bus_write(AXP209_DCDC2_VOLTAGE, current);
if (rc)
break;
}
@@ -53,68 +50,106 @@ int axp209_set_dcdc2(int mvolt)
return rc;
}
-int axp209_set_dcdc3(int mvolt)
+int axp_set_dcdc3(unsigned int mvolt)
{
u8 cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
+ int rc;
- return axp209_write(AXP209_DCDC3_VOLTAGE, cfg);
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
+ AXP209_OUTPUT_CTRL_DCDC3);
+
+ rc = pmic_bus_write(AXP209_DCDC3_VOLTAGE, cfg);
+ if (rc)
+ return rc;
+
+ return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_DCDC3);
}
-int axp209_set_ldo2(int mvolt)
+int axp_set_aldo2(unsigned int mvolt)
{
int rc;
u8 cfg, reg;
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
+ AXP209_OUTPUT_CTRL_LDO2);
+
cfg = axp209_mvolt_to_cfg(mvolt, 1800, 3300, 100);
- rc = axp209_read(AXP209_LDO24_VOLTAGE, &reg);
+ rc = pmic_bus_read(AXP209_LDO24_VOLTAGE, &reg);
if (rc)
return rc;
/* LDO2 configuration is in upper 4 bits */
reg = (reg & 0x0f) | (cfg << 4);
- return axp209_write(AXP209_LDO24_VOLTAGE, reg);
+ rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
+ if (rc)
+ return rc;
+
+ return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO2);
}
-int axp209_set_ldo3(int mvolt)
+int axp_set_aldo3(unsigned int mvolt)
{
u8 cfg;
+ int rc;
+
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
+ AXP209_OUTPUT_CTRL_LDO3);
if (mvolt == -1)
cfg = 0x80; /* determined by LDO3IN pin */
else
cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
- return axp209_write(AXP209_LDO3_VOLTAGE, cfg);
+ rc = pmic_bus_write(AXP209_LDO3_VOLTAGE, cfg);
+ if (rc)
+ return rc;
+
+ return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO3);
}
-int axp209_set_ldo4(int mvolt)
+int axp_set_aldo4(unsigned int mvolt)
{
int rc;
- static const int vindex[] = {
+ static const unsigned int vindex[] = {
1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500,
2700, 2800, 3000, 3100, 3200, 3300
};
u8 cfg, reg;
+ if (mvolt == 0)
+ return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
+ AXP209_OUTPUT_CTRL_LDO4);
+
/* Translate mvolt to register cfg value, requested <= selected */
for (cfg = 15; vindex[cfg] > mvolt && cfg > 0; cfg--);
- rc = axp209_read(AXP209_LDO24_VOLTAGE, &reg);
+ rc = pmic_bus_read(AXP209_LDO24_VOLTAGE, &reg);
if (rc)
return rc;
/* LDO4 configuration is in lower 4 bits */
reg = (reg & 0xf0) | (cfg << 0);
- return axp209_write(AXP209_LDO24_VOLTAGE, reg);
+ rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
+ if (rc)
+ return rc;
+
+ return pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO4);
}
-int axp209_init(void)
+int axp_init(void)
{
u8 ver;
int i, rc;
- rc = axp209_read(AXP209_CHIP_VERSION, &ver);
+ rc = pmic_bus_init();
+ if (rc)
+ return rc;
+
+ rc = pmic_bus_read(AXP209_CHIP_VERSION, &ver);
if (rc)
return rc;
@@ -126,32 +161,10 @@ int axp209_init(void)
/* Mask all interrupts */
for (i = AXP209_IRQ_ENABLE1; i <= AXP209_IRQ_ENABLE5; i++) {
- rc = axp209_write(i, 0);
+ rc = pmic_bus_write(i, 0);
if (rc)
return rc;
}
return 0;
}
-
-int axp209_poweron_by_dc(void)
-{
- u8 v;
-
- if (axp209_read(AXP209_POWER_STATUS, &v))
- return 0;
-
- return (v & AXP209_POWER_STATUS_ON_BY_DC);
-}
-
-int axp209_power_button(void)
-{
- u8 v;
-
- if (axp209_read(AXP209_IRQ_STATUS5, &v))
- return 0;
-
- axp209_write(AXP209_IRQ_STATUS5, AXP209_IRQ5_PEK_DOWN);
-
- return v & AXP209_IRQ5_PEK_DOWN;
-}
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index 7bbaec87e4..65802e4a71 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -12,9 +12,8 @@
#include <common.h>
#include <errno.h>
-#include <asm/arch/gpio.h>
#include <asm/arch/pmic_bus.h>
-#include <axp221.h>
+#include <axp_pmic.h>
static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div)
{
@@ -26,7 +25,7 @@ static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div)
return (mvolt - min) / div;
}
-int axp221_set_dcdc1(unsigned int mvolt)
+int axp_set_dcdc1(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100);
@@ -48,7 +47,7 @@ int axp221_set_dcdc1(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_DCDC1_EN);
}
-int axp221_set_dcdc2(unsigned int mvolt)
+int axp_set_dcdc2(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
@@ -65,7 +64,7 @@ int axp221_set_dcdc2(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_DCDC2_EN);
}
-int axp221_set_dcdc3(unsigned int mvolt)
+int axp_set_dcdc3(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20);
@@ -82,7 +81,7 @@ int axp221_set_dcdc3(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_DCDC3_EN);
}
-int axp221_set_dcdc4(unsigned int mvolt)
+int axp_set_dcdc4(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
@@ -99,7 +98,7 @@ int axp221_set_dcdc4(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_DCDC4_EN);
}
-int axp221_set_dcdc5(unsigned int mvolt)
+int axp_set_dcdc5(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50);
@@ -116,7 +115,7 @@ int axp221_set_dcdc5(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_DCDC5_EN);
}
-int axp221_set_dldo1(unsigned int mvolt)
+int axp_set_dldo1(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -133,7 +132,7 @@ int axp221_set_dldo1(unsigned int mvolt)
AXP221_OUTPUT_CTRL2_DLDO1_EN);
}
-int axp221_set_dldo2(unsigned int mvolt)
+int axp_set_dldo2(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -150,7 +149,7 @@ int axp221_set_dldo2(unsigned int mvolt)
AXP221_OUTPUT_CTRL2_DLDO2_EN);
}
-int axp221_set_dldo3(unsigned int mvolt)
+int axp_set_dldo3(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -167,7 +166,7 @@ int axp221_set_dldo3(unsigned int mvolt)
AXP221_OUTPUT_CTRL2_DLDO3_EN);
}
-int axp221_set_dldo4(unsigned int mvolt)
+int axp_set_dldo4(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -184,7 +183,7 @@ int axp221_set_dldo4(unsigned int mvolt)
AXP221_OUTPUT_CTRL2_DLDO4_EN);
}
-int axp221_set_aldo1(unsigned int mvolt)
+int axp_set_aldo1(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -201,7 +200,7 @@ int axp221_set_aldo1(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_ALDO1_EN);
}
-int axp221_set_aldo2(unsigned int mvolt)
+int axp_set_aldo2(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -218,7 +217,7 @@ int axp221_set_aldo2(unsigned int mvolt)
AXP221_OUTPUT_CTRL1_ALDO2_EN);
}
-int axp221_set_aldo3(unsigned int mvolt)
+int axp_set_aldo3(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -235,7 +234,7 @@ int axp221_set_aldo3(unsigned int mvolt)
AXP221_OUTPUT_CTRL3_ALDO3_EN);
}
-int axp221_set_eldo(int eldo_num, unsigned int mvolt)
+int axp_set_eldo(int eldo_num, unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
@@ -268,16 +267,11 @@ int axp221_set_eldo(int eldo_num, unsigned int mvolt)
return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, bits);
}
-int axp221_init(void)
+int axp_init(void)
{
- /* This cannot be 0 because it is used in SPL before BSS is ready */
- static int needs_init = 1;
u8 axp_chip_id;
int ret;
- if (!needs_init)
- return 0;
-
ret = pmic_bus_init();
if (ret)
return ret;
@@ -289,16 +283,15 @@ int axp221_init(void)
if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17))
return -ENODEV;
- needs_init = 0;
return 0;
}
-int axp221_get_sid(unsigned int *sid)
+int axp_get_sid(unsigned int *sid)
{
u8 *dest = (u8 *)sid;
int i, ret;
- ret = axp221_init();
+ ret = pmic_bus_init();
if (ret)
return ret;
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
new file mode 100644
index 0000000000..437224b549
--- /dev/null
+++ b/drivers/remoteproc/Kconfig
@@ -0,0 +1,24 @@
+#
+# (C) Copyright 2015
+# Texas Instruments Incorporated - http://www.ti.com/
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+menu "Remote Processor drivers"
+
+# REMOTEPROC gets selected by drivers as needed
+# All users should depend on DM
+config REMOTEPROC
+ bool
+ depends on DM
+
+# Please keep the configuration alphabetically sorted.
+config REMOTEPROC_SANDBOX
+ bool "Support for Test processor for Sandbox"
+ select REMOTEPROC
+ depends on DM
+ depends on SANDBOX
+ help
+ Say 'y' here to add support for test processor which does dummy
+ operations for sandbox platform.
+endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
new file mode 100644
index 0000000000..720aa6e647
--- /dev/null
+++ b/drivers/remoteproc/Makefile
@@ -0,0 +1,10 @@
+#
+# (C) Copyright 2015
+# Texas Instruments Incorporated - http://www.ti.com/
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_REMOTEPROC) += rproc-uclass.o
+
+# Remote proc drivers - Please keep this list alphabetically sorted.
+obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c
new file mode 100644
index 0000000000..a421e12e5d
--- /dev/null
+++ b/drivers/remoteproc/rproc-uclass.c
@@ -0,0 +1,417 @@
+/*
+ * (C) Copyright 2015
+ * Texas Instruments Incorporated - http://www.ti.com/
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <remoteproc.h>
+#include <asm/io.h>
+#include <dm/device-internal.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * for_each_remoteproc_device() - iterate through the list of rproc devices
+ * @fn: check function to call per match, if this function returns fail,
+ * iteration is aborted with the resultant error value
+ * @skip_dev: Device to skip calling the callback about.
+ * @data: Data to pass to the callback function
+ *
+ * Return: 0 if none of the callback returned a non 0 result, else returns the
+ * result from the callback function
+ */
+static int for_each_remoteproc_device(int (*fn) (struct udevice *dev,
+ struct dm_rproc_uclass_pdata *uc_pdata,
+ const void *data),
+ struct udevice *skip_dev,
+ const void *data)
+{
+ struct udevice *dev;
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int ret;
+
+ for (ret = uclass_find_first_device(UCLASS_REMOTEPROC, &dev); dev;
+ ret = uclass_find_next_device(&dev)) {
+ if (ret || dev == skip_dev)
+ continue;
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ret = fn(dev, uc_pdata, data);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * _rproc_name_is_unique() - iteration helper to check if rproc name is unique
+ * @dev: device that we are checking name for
+ * @uc_pdata: uclass platform data
+ * @data: compare data (this is the name we want to ensure is unique)
+ *
+ * Return: 0 is there is no match(is unique); if there is a match(we dont
+ * have a unique name), return -EINVAL.
+ */
+static int _rproc_name_is_unique(struct udevice *dev,
+ struct dm_rproc_uclass_pdata *uc_pdata,
+ const void *data)
+{
+ const char *check_name = data;
+
+ /* devices not yet populated with data - so skip them */
+ if (!uc_pdata->name && check_name)
+ return 0;
+
+ /* Return 0 to search further if we dont match */
+ if (strlen(uc_pdata->name) != strlen(check_name))
+ return 0;
+
+ if (!strcmp(uc_pdata->name, check_name))
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * rproc_name_is_unique() - Check if the rproc name is unique
+ * @check_dev: Device we are attempting to ensure is unique
+ * @check_name: Name we are trying to ensure is unique.
+ *
+ * Return: true if we have a unique name, false if name is not unique.
+ */
+static bool rproc_name_is_unique(struct udevice *check_dev,
+ const char *check_name)
+{
+ int ret;
+
+ ret = for_each_remoteproc_device(_rproc_name_is_unique,
+ check_dev, check_name);
+ return ret ? false : true;
+}
+
+/**
+ * rproc_pre_probe() - Pre probe accessor for the uclass
+ * @dev: device for which we are preprobing
+ *
+ * Parses and fills up the uclass pdata for use as needed by core and
+ * remote proc drivers.
+ *
+ * Return: 0 if all wernt ok, else appropriate error value.
+ */
+static int rproc_pre_probe(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ const struct dm_rproc_ops *ops;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ /* See if we need to populate via fdt */
+
+ if (!dev->platdata) {
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ int node = dev->of_offset;
+ const void *blob = gd->fdt_blob;
+ bool tmp;
+ if (!blob) {
+ debug("'%s' no dt?\n", dev->name);
+ return -EINVAL;
+ }
+ debug("'%s': using fdt\n", dev->name);
+ uc_pdata->name = fdt_getprop(blob, node,
+ "remoteproc-name", NULL);
+
+ /* Default is internal memory mapped */
+ uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED;
+ tmp = fdtdec_get_bool(blob, node,
+ "remoteproc-internal-memory-mapped");
+ if (tmp)
+ uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED;
+#else
+ /* Nothing much we can do about this, can we? */
+ return -EINVAL;
+#endif
+
+ } else {
+ struct dm_rproc_uclass_pdata *pdata = dev->platdata;
+
+ debug("'%s': using legacy data\n", dev->name);
+ if (pdata->name)
+ uc_pdata->name = pdata->name;
+ uc_pdata->mem_type = pdata->mem_type;
+ uc_pdata->driver_plat_data = pdata->driver_plat_data;
+ }
+
+ /* Else try using device Name */
+ if (!uc_pdata->name)
+ uc_pdata->name = dev->name;
+ if (!uc_pdata->name) {
+ debug("Unnamed device!");
+ return -EINVAL;
+ }
+
+ if (!rproc_name_is_unique(dev, uc_pdata->name)) {
+ debug("%s duplicate name '%s'\n", dev->name, uc_pdata->name);
+ return -EINVAL;
+ }
+
+ ops = rproc_get_ops(dev);
+ if (!ops) {
+ debug("%s driver has no ops?\n", dev->name);
+ return -EINVAL;
+ }
+
+ if (!ops->load || !ops->start) {
+ debug("%s driver has missing mandatory ops?\n", dev->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * rproc_post_probe() - post probe accessor for the uclass
+ * @dev: deivce we finished probing
+ *
+ * initiate init function after the probe is completed. This allows
+ * the remote processor drivers to split up the initializations between
+ * probe and init as needed.
+ *
+ * Return: if the remote proc driver has a init routine, invokes it and
+ * hands over the return value. overall, 0 if all went well, else appropriate
+ * error value.
+ */
+static int rproc_post_probe(struct udevice *dev)
+{
+ const struct dm_rproc_ops *ops;
+
+ ops = rproc_get_ops(dev);
+ if (!ops) {
+ debug("%s driver has no ops?\n", dev->name);
+ return -EINVAL;
+ }
+
+ if (ops->init)
+ return ops->init(dev);
+
+ return 0;
+}
+
+UCLASS_DRIVER(rproc) = {
+ .id = UCLASS_REMOTEPROC,
+ .name = "remoteproc",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+ .pre_probe = rproc_pre_probe,
+ .post_probe = rproc_post_probe,
+ .per_device_platdata_auto_alloc_size =
+ sizeof(struct dm_rproc_uclass_pdata),
+};
+
+/* Remoteproc subsystem access functions */
+/**
+ * _rproc_probe_dev() - iteration helper to probe a rproc device
+ * @dev: device to probe
+ * @uc_pdata: uclass data allocated for the device
+ * @data: unused
+ *
+ * Return: 0 if all ok, else appropriate error value.
+ */
+static int _rproc_probe_dev(struct udevice *dev,
+ struct dm_rproc_uclass_pdata *uc_pdata,
+ const void *data)
+{
+ int ret;
+
+ ret = device_probe(dev);
+
+ if (ret)
+ debug("%s: Failed to initialize - %d\n", dev->name, ret);
+ return ret;
+}
+
+/**
+ * _rproc_dev_is_probed() - check if the device has been probed
+ * @dev: device to check
+ * @uc_pdata: unused
+ * @data: unused
+ *
+ * Return: -EAGAIN if not probed else return 0
+ */
+static int _rproc_dev_is_probed(struct udevice *dev,
+ struct dm_rproc_uclass_pdata *uc_pdata,
+ const void *data)
+{
+ if (dev->flags & DM_FLAG_ACTIVATED)
+ return 0;
+
+ return -EAGAIN;
+}
+
+bool rproc_is_initialized(void)
+{
+ int ret = for_each_remoteproc_device(_rproc_dev_is_probed, NULL, NULL);
+ return ret ? false : true;
+}
+
+int rproc_init(void)
+{
+ int ret;
+
+ if (rproc_is_initialized()) {
+ debug("Already initialized\n");
+ return -EINVAL;
+ }
+
+ ret = for_each_remoteproc_device(_rproc_probe_dev, NULL, NULL);
+ return ret;
+}
+
+int rproc_load(int id, ulong addr, ulong size)
+{
+ struct udevice *dev = NULL;
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ const struct dm_rproc_ops *ops;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
+ if (ret) {
+ debug("Unknown remote processor id '%d' requested(%d)\n",
+ id, ret);
+ return ret;
+ }
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ops = rproc_get_ops(dev);
+ if (!ops) {
+ debug("%s driver has no ops?\n", dev->name);
+ return -EINVAL;
+ }
+
+ debug("Loading to '%s' from address 0x%08lX size of %lu bytes\n",
+ uc_pdata->name, addr, size);
+ if (ops->load)
+ return ops->load(dev, addr, size);
+
+ debug("%s: data corruption?? mandatory function is missing!\n",
+ dev->name);
+
+ return -EINVAL;
+};
+
+/*
+ * Completely internal helper enums..
+ * Keeping this isolated helps this code evolve independent of other
+ * parts..
+ */
+enum rproc_ops {
+ RPROC_START,
+ RPROC_STOP,
+ RPROC_RESET,
+ RPROC_PING,
+ RPROC_RUNNING,
+};
+
+/**
+ * _rproc_ops_wrapper() - wrapper for invoking remote proc driver callback
+ * @id: id of the remote processor
+ * @op: one of rproc_ops that indicate what operation to invoke
+ *
+ * Most of the checks and verification for remoteproc operations are more
+ * or less same for almost all operations. This allows us to put a wrapper
+ * and use the common checks to allow the driver to function appropriately.
+ *
+ * Return: 0 if all ok, else appropriate error value.
+ */
+static int _rproc_ops_wrapper(int id, enum rproc_ops op)
+{
+ struct udevice *dev = NULL;
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ const struct dm_rproc_ops *ops;
+ int (*fn)(struct udevice *dev);
+ bool mandatory = false;
+ char *op_str;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
+ if (ret) {
+ debug("Unknown remote processor id '%d' requested(%d)\n",
+ id, ret);
+ return ret;
+ }
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ops = rproc_get_ops(dev);
+ if (!ops) {
+ debug("%s driver has no ops?\n", dev->name);
+ return -EINVAL;
+ }
+ switch (op) {
+ case RPROC_START:
+ fn = ops->start;
+ mandatory = true;
+ op_str = "Starting";
+ break;
+ case RPROC_STOP:
+ fn = ops->stop;
+ op_str = "Stopping";
+ break;
+ case RPROC_RESET:
+ fn = ops->reset;
+ op_str = "Resetting";
+ break;
+ case RPROC_RUNNING:
+ fn = ops->is_running;
+ op_str = "Checking if running:";
+ break;
+ case RPROC_PING:
+ fn = ops->ping;
+ op_str = "Pinging";
+ break;
+ default:
+ debug("what is '%d' operation??\n", op);
+ return -EINVAL;
+ }
+
+ debug("%s %s...\n", op_str, uc_pdata->name);
+ if (fn)
+ return fn(dev);
+
+ if (mandatory)
+ debug("%s: data corruption?? mandatory function is missing!\n",
+ dev->name);
+
+ return -ENOSYS;
+}
+
+int rproc_start(int id)
+{
+ return _rproc_ops_wrapper(id, RPROC_START);
+};
+
+int rproc_stop(int id)
+{
+ return _rproc_ops_wrapper(id, RPROC_STOP);
+};
+
+int rproc_reset(int id)
+{
+ return _rproc_ops_wrapper(id, RPROC_RESET);
+};
+
+int rproc_ping(int id)
+{
+ return _rproc_ops_wrapper(id, RPROC_PING);
+};
+
+int rproc_is_running(int id)
+{
+ return _rproc_ops_wrapper(id, RPROC_RUNNING);
+};
diff --git a/drivers/remoteproc/sandbox_testproc.c b/drivers/remoteproc/sandbox_testproc.c
new file mode 100644
index 0000000000..004c7792d1
--- /dev/null
+++ b/drivers/remoteproc/sandbox_testproc.c
@@ -0,0 +1,336 @@
+/*
+ * (C) Copyright 2015
+ * Texas Instruments Incorporated - http://www.ti.com/
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <remoteproc.h>
+
+/**
+ * enum sandbox_state - different device states
+ * @sb_booted: Entry condition, just booted
+ * @sb_init: Initialized (basic environment is ready)
+ * @sb_reset: Held in reset (accessible, but not running)
+ * @sb_loaded: Loaded with image (but not running)
+ * @sb_running: Processor is running
+ */
+enum sandbox_state {
+ sb_booted,
+ sb_init,
+ sb_reset,
+ sb_loaded,
+ sb_running
+};
+
+/**
+ * struct sandbox_test_devdata - private data per device
+ * @current_state: device current state
+ */
+struct sandbox_test_devdata {
+ enum sandbox_state current_state;
+};
+
+/**
+ * sandbox_dev_move_to_state() - statemachine for our dummy device
+ * @dev: device to switch state
+ * @next_state: next proposed state
+ *
+ * This tries to follow the following statemachine:
+ * Entry
+ * |
+ * v
+ * +-------+
+ * +---+ init |
+ * | | | <---------------------+
+ * | +-------+ |
+ * | |
+ * | |
+ * | +--------+ |
+ * Load| | reset | |
+ * | | | <----------+ |
+ * | +--------+ | |
+ * | |Load | |
+ * | | | |
+ * | +----v----+ reset | |
+ * +-> | | (opt) | |
+ * | Loaded +-----------+ |
+ * | | |
+ * +----+----+ |
+ * | Start |
+ * +---v-----+ (opt) |
+ * +->| Running | Stop |
+ * Ping +- | +--------------------+
+ * (opt) +---------+
+ *
+ * (is_running does not change state)
+ *
+ * Return: 0 when valid state transition is seen, else returns -EINVAL
+ */
+static int sandbox_dev_move_to_state(struct udevice *dev,
+ enum sandbox_state next_state)
+{
+ struct sandbox_test_devdata *ddata = dev_get_priv(dev);
+
+ /* No state transition is OK */
+ if (ddata->current_state == next_state)
+ return 0;
+
+ debug("current_state=%d, next_state=%d\n", ddata->current_state,
+ next_state);
+ switch (ddata->current_state) {
+ case sb_booted:
+ if (next_state == sb_init)
+ goto ok_state;
+ break;
+
+ case sb_init:
+ if (next_state == sb_reset || next_state == sb_loaded)
+ goto ok_state;
+ break;
+
+ case sb_reset:
+ if (next_state == sb_loaded || next_state == sb_init)
+ goto ok_state;
+ break;
+
+ case sb_loaded:
+ if (next_state == sb_reset || next_state == sb_init ||
+ next_state == sb_running)
+ goto ok_state;
+ break;
+
+ case sb_running:
+ if (next_state == sb_reset || next_state == sb_init)
+ goto ok_state;
+ break;
+ };
+ return -EINVAL;
+
+ok_state:
+ ddata->current_state = next_state;
+ return 0;
+}
+
+/**
+ * sandbox_testproc_probe() - basic probe function
+ * @dev: test proc device that is being probed.
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int sandbox_testproc_probe(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ struct sandbox_test_devdata *ddata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ddata = dev_get_priv(dev);
+ if (!ddata) {
+ debug("%s: platform private data missing\n", uc_pdata->name);
+ return -EINVAL;
+ }
+ ret = sandbox_dev_move_to_state(dev, sb_booted);
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+
+ return ret;
+}
+
+/**
+ * sandbox_testproc_init() - Simple initialization function
+ * @dev: device to operate upon
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int sandbox_testproc_init(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ret = sandbox_dev_move_to_state(dev, sb_init);
+
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+ if (ret)
+ debug("%s init failed\n", uc_pdata->name);
+
+ return ret;
+}
+
+/**
+ * sandbox_testproc_reset() - Reset the remote processor
+ * @dev: device to operate upon
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int sandbox_testproc_reset(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ret = sandbox_dev_move_to_state(dev, sb_reset);
+
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+
+ if (ret)
+ debug("%s reset failed\n", uc_pdata->name);
+ return ret;
+}
+
+/**
+ * sandbox_testproc_load() - (replace: short desc)
+ * @dev: device to operate upon
+ * @addr: Address of the binary image to load
+ * @size: Size (in bytes) of the binary image to load
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int sandbox_testproc_load(struct udevice *dev, ulong addr, ulong size)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ret = sandbox_dev_move_to_state(dev, sb_loaded);
+
+ debug("%s: called(%d) Loading to %08lX %lu size\n",
+ uc_pdata->name, ret, addr, size);
+
+ if (ret)
+ debug("%s load failed\n", uc_pdata->name);
+ return ret;
+}
+
+/**
+ * sandbox_testproc_start() - Start the remote processor
+ * @dev: device to operate upon
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int sandbox_testproc_start(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ret = sandbox_dev_move_to_state(dev, sb_running);
+
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+
+ if (ret)
+ debug("%s start failed\n", uc_pdata->name);
+ return ret;
+}
+
+/**
+ * sandbox_testproc_stop() - Stop the remote processor
+ * @dev: device to operate upon
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int sandbox_testproc_stop(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ ret = sandbox_dev_move_to_state(dev, sb_init);
+
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+
+ if (ret)
+ debug("%s stop failed\n", uc_pdata->name);
+ return ret;
+}
+
+/**
+ * sandbox_testproc_is_running() - Check if remote processor is running
+ * @dev: device to operate upon
+ *
+ * Return: 0 if running, 1 if not running
+ */
+static int sandbox_testproc_is_running(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ struct sandbox_test_devdata *ddata;
+ int ret = 1;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ddata = dev_get_priv(dev);
+
+ if (ddata->current_state == sb_running)
+ ret = 0;
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+
+ return ret;
+}
+
+/**
+ * sandbox_testproc_ping() - Try pinging remote processor
+ * @dev: device to operate upon
+ *
+ * Return: 0 if running, -EINVAL if not running
+ */
+static int sandbox_testproc_ping(struct udevice *dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ struct sandbox_test_devdata *ddata;
+ int ret;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ddata = dev_get_priv(dev);
+
+ if (ddata->current_state == sb_running)
+ ret = 0;
+ else
+ ret = -EINVAL;
+
+ debug("%s: called(%d)\n", uc_pdata->name, ret);
+ if (ret)
+ debug("%s: No response.(Not started?)\n", uc_pdata->name);
+
+ return ret;
+}
+
+static const struct dm_rproc_ops sandbox_testproc_ops = {
+ .init = sandbox_testproc_init,
+ .reset = sandbox_testproc_reset,
+ .load = sandbox_testproc_load,
+ .start = sandbox_testproc_start,
+ .stop = sandbox_testproc_stop,
+ .is_running = sandbox_testproc_is_running,
+ .ping = sandbox_testproc_ping,
+};
+
+static const struct udevice_id sandbox_ids[] = {
+ {.compatible = "sandbox,test-processor"},
+ {}
+};
+
+U_BOOT_DRIVER(sandbox_testproc) = {
+ .name = "sandbox_test_proc",
+ .of_match = sandbox_ids,
+ .id = UCLASS_REMOTEPROC,
+ .ops = &sandbox_testproc_ops,
+ .probe = sandbox_testproc_probe,
+ .priv_auto_alloc_size = sizeof(struct sandbox_test_devdata),
+};
+
+/* TODO(nm@ti.com): Remove this along with non-DT support */
+static struct dm_rproc_uclass_pdata proc_3_test = {
+ .name = "proc_3_legacy",
+ .mem_type = RPROC_INTERNAL_MEMORY_MAPPED,
+};
+
+U_BOOT_DEVICE(proc_3_demo) = {
+ .name = "sandbox_test_proc",
+ .platdata = &proc_3_test,
+};
diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c
index 363ade33e3..da804d5459 100644
--- a/drivers/rtc/mc146818.c
+++ b/drivers/rtc/mc146818.c
@@ -192,7 +192,7 @@ static void mc146818_init(void)
/* Clear any pending interrupts */
mc146818_read8(RTC_CONFIG_C);
}
-#endif
+#endif /* CONFIG_CMD_DATE */
#ifdef CONFIG_DM_RTC
@@ -225,7 +225,7 @@ static int rtc_mc146818_write8(struct udevice *dev, unsigned int reg, int val)
return 0;
}
-static int rtc_mc146818_bind(struct udevice *dev)
+static int rtc_mc146818_probe(struct udevice *dev)
{
mc146818_init();
@@ -249,7 +249,7 @@ U_BOOT_DRIVER(rtc_mc146818) = {
.name = "rtc_mc146818",
.id = UCLASS_RTC,
.of_match = rtc_mc146818_ids,
- .bind = rtc_mc146818_bind,
+ .probe = rtc_mc146818_probe,
.ops = &rtc_mc146818_ops,
};
diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c
index fe74c69f97..300e9b30ec 100644
--- a/drivers/rtc/rtc-uclass.c
+++ b/drivers/rtc/rtc-uclass.c
@@ -68,7 +68,7 @@ int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep)
for (i = 0; i < sizeof(value); i++) {
ret = rtc_read8(dev, reg + i);
- if (ret)
+ if (ret < 0)
return ret;
value |= ret << (i << 3);
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ddb725d326..ac5920ad5a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -109,6 +109,27 @@ config DEBUG_UART_SHIFT
value. Use this value to specify the shift to use, where 0=byte
registers, 2=32-bit word registers, etc.
+config DEBUG_UART_BOARD_INIT
+ bool "Enable board-specific debug UART init"
+ depends on DEBUG_UART
+ help
+ Some boards need to set things up before the debug UART can be used.
+ On these boards a call to debug_uart_init() is insufficient. When
+ this option is enabled, the function board_debug_uart_init() will
+ be called when debug_uart_init() is called. You can put any code
+ here that is needed to set up the UART ready for use, such as set
+ pin multiplexing or enable clocks.
+
+config DEBUG_UART_ANNOUNCE
+ bool "Show a message when the debug UART starts up"
+ depends on DEBUG_UART
+ help
+ Enable this option to show a message when the debug UART is ready
+ for use. You will see a message like "<debug_uart> " as soon as
+ U-Boot has the UART ready for use (i.e. your code calls
+ debug_uart_init()). This can be useful just as a check that
+ everything is working.
+
config ROCKCHIP_SERIAL
bool "Rockchip on-chip UART support"
depends on ARCH_ROCKCHIP && DM_SERIAL
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 6275a11a0c..6433844f18 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -257,7 +257,7 @@ int NS16550_tstc(NS16550_t com_port)
(1 << CONFIG_DEBUG_UART_SHIFT), \
CONFIG_DEBUG_UART_SHIFT)
-void debug_uart_init(void)
+static inline void _debug_uart_init(void)
{
struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
int baud_divisor;
diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c
index cf57d8977b..ea25c25a68 100644
--- a/drivers/serial/serial_efi.c
+++ b/drivers/serial/serial_efi.c
@@ -107,7 +107,7 @@ static int serial_efi_pending(struct udevice *dev, bool input)
* There is nothing to init here since the EFI console is already running by
* the time we enter U-Boot.
*/
-void debug_uart_init(void)
+static inline void _debug_uart_init(void)
{
}
diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c
index e8d544f0da..891cd7b7ed 100644
--- a/drivers/serial/serial_omap.c
+++ b/drivers/serial/serial_omap.c
@@ -12,10 +12,16 @@
DECLARE_GLOBAL_DATA_PTR;
+#define DEFAULT_CLK_SPEED 48000000 /* 48Mhz */
+
#if CONFIG_IS_ENABLED(OF_CONTROL)
static const struct udevice_id omap_serial_ids[] = {
+ { .compatible = "ti,omap2-uart" },
{ .compatible = "ti,omap3-uart" },
{ .compatible = "ti,omap4-uart" },
+ { .compatible = "ti,am3352-uart" },
+ { .compatible = "ti,am4372-uart" },
+ { .compatible = "ti,dra742-uart" },
{ }
};
@@ -28,7 +34,7 @@ static int omap_serial_ofdata_to_platdata(struct udevice *dev)
if (ret)
return ret;
plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
- "clock-frequency", -1);
+ "clock-frequency", DEFAULT_CLK_SPEED);
plat->reg_shift = 2;
return 0;
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 3f0b588254..feba467d80 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -207,7 +207,7 @@ U_BOOT_DRIVER(serial_s5p) = {
#include <debug_uart.h>
-void debug_uart_init(void)
+static inline void _debug_uart_init(void)
{
struct s5p_uart *uart = (struct s5p_uart *)CONFIG_DEBUG_UART_BASE;
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 2e388e7ad9..be4c0a3353 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -133,7 +133,8 @@ static int get_ich_version(uint16_t device_id)
(device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) ||
device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC ||
- device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC)
+ device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC ||
+ device_id == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LPC)
return 9;
return 0;
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index ca01a018b5..ece48e668c 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -554,7 +554,7 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req)
static void cb_oem(struct usb_ep *ep, struct usb_request *req)
{
char *cmd = req->buf;
-#ifdef CONFIG_FASTBOOT_FLASH
+#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
if (strncmp("format", cmd + 4, 6) == 0) {
char cmdbuf[32];
sprintf(cmdbuf, "gpt write mmc %x $partitions",
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b30b43da3b..2a2bffe06f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -52,6 +52,13 @@ config USB_EHCI
if USB_EHCI_HCD
+config USB_EHCI_MARVELL
+ bool "Support for MVEBU (AXP / A38x) on-chip EHCI USB controller"
+ depends on ARCH_MVEBU
+ default y
+ ---help---
+ Enables support for the on-chip EHCI controller on MVEBU SoCs.
+
config USB_EHCI_MX6
bool "Support for i.MX6 on-chip EHCI USB controller"
depends on ARCH_MX6
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 50fa01c079..5b0f46aaef 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -12,6 +12,7 @@
#include "ehci.h"
#include <linux/mbus.h>
#include <asm/arch/cpu.h>
+#include <dm.h>
#if defined(CONFIG_KIRKWOOD)
#include <asm/arch/soc.h>
@@ -28,24 +29,19 @@ DECLARE_GLOBAL_DATA_PTR;
/*
* USB 2.0 Bridge Address Decoding registers setup
*/
-#ifdef CONFIG_ARMADA_XP
+#ifdef CONFIG_DM_USB
-/*
- * Armada XP and Armada 38x have different base addresses for
- * the USB 2.0 EHCI host controller. So we need to provide
- * a mechnism to support both here.
- */
-#define MVUSB0_BASE \
- (mvebu_soc_family() == MVEBU_SOC_A38X ? \
- MVEBU_USB20_BASE : MVEBU_AXP_USB_BASE)
-#define MVUSB_BASE(port) MVUSB0_BASE + ((port) << 12)
+struct ehci_mvebu_priv {
+ struct ehci_ctrl ehci;
+ fdt_addr_t hcd_base;
+};
/*
* Once all the older Marvell SoC's (Orion, Kirkwood) are converted
* to the common mvebu archticture including the mbus setup, this
* will be the only function needed to configure the access windows
*/
-static void usb_brg_adrdec_setup(int index)
+static void usb_brg_adrdec_setup(u32 base)
{
const struct mbus_dram_target_info *dram;
int i;
@@ -53,8 +49,8 @@ static void usb_brg_adrdec_setup(int index)
dram = mvebu_mbus_dram_info();
for (i = 0; i < 4; i++) {
- writel(0, MVUSB_BASE(index) + USB_WINDOW_CTRL(i));
- writel(0, MVUSB_BASE(index) + USB_WINDOW_BASE(i));
+ writel(0, base + USB_WINDOW_CTRL(i));
+ writel(0, base + USB_WINDOW_BASE(i));
}
for (i = 0; i < dram->num_cs; i++) {
@@ -63,12 +59,69 @@ static void usb_brg_adrdec_setup(int index)
/* Write size, attributes and target id to control register */
writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
(dram->mbus_dram_target_id << 4) | 1,
- MVUSB_BASE(index) + USB_WINDOW_CTRL(i));
+ base + USB_WINDOW_CTRL(i));
/* Write base address to base register */
- writel(cs->base, MVUSB_BASE(index) + USB_WINDOW_BASE(i));
+ writel(cs->base, base + USB_WINDOW_BASE(i));
}
}
+
+static int ehci_mvebu_probe(struct udevice *dev)
+{
+ struct ehci_mvebu_priv *priv = dev_get_priv(dev);
+ struct ehci_hccr *hccr;
+ struct ehci_hcor *hcor;
+
+ /*
+ * Get the base address for EHCI controller from the device node
+ */
+ priv->hcd_base = dev_get_addr(dev);
+ if (priv->hcd_base == FDT_ADDR_T_NONE) {
+ debug("Can't get the EHCI register base address\n");
+ return -ENXIO;
+ }
+
+ usb_brg_adrdec_setup(priv->hcd_base);
+
+ hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100);
+ hcor = (struct ehci_hcor *)
+ ((u32)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ debug("ehci-marvell: init hccr %x and hcor %x hc_length %d\n",
+ (u32)hccr, (u32)hcor,
+ (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_mvebu_remove(struct udevice *dev)
+{
+ int ret;
+
+ ret = ehci_deregister(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct udevice_id ehci_usb_ids[] = {
+ { .compatible = "marvell,orion-ehci", },
+ { }
+};
+
+U_BOOT_DRIVER(ehci_mvebu) = {
+ .name = "ehci_mvebu",
+ .id = UCLASS_USB,
+ .of_match = ehci_usb_ids,
+ .probe = ehci_mvebu_probe,
+ .remove = ehci_mvebu_remove,
+ .ops = &ehci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct ehci_mvebu_priv),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
#else
#define MVUSB_BASE(port) MVUSB0_BASE
@@ -112,7 +165,6 @@ static void usb_brg_adrdec_setup(int index)
writel(base, MVUSB0_BASE + USB_WINDOW_BASE(i));
}
}
-#endif
/*
* Create the appropriate control structures to manage
@@ -142,3 +194,5 @@ int ehci_hcd_stop(int index)
{
return 0;
}
+
+#endif /* CONFIG_DM_USB */
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index fc1aea3f06..9fee66a2a4 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -15,7 +15,7 @@
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <axp221.h>
+#include <axp_pmic.h>
#include <errno.h>
#include <fdtdec.h>
#include <fdt_support.h>
@@ -1217,10 +1217,10 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
/*
* The anx9804 needs 1.8V from eldo3, we do this here
- * and not via CONFIG_AXP221_ELDO3 from board_init()
+ * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
* to avoid turning this on when using hdmi output.
*/
- axp221_set_eldo(3, 1800);
+ axp_set_eldo(3, 1800);
anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
ANX9804_DATA_RATE_1620M,
sunxi_display.depth);
diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c
index 4e6d070a5f..a19651f5f3 100644
--- a/drivers/video/vesa_fb.c
+++ b/drivers/video/vesa_fb.c
@@ -34,7 +34,7 @@ void *video_hw_init(void)
}
if (vbe_get_video_info(gdev)) {
dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
- if (dev == -1) {
+ if (dev < 0) {
printf("no card detected\n");
return NULL;
}