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/bios_emulator/atibios.c3
-rw-r--r--drivers/core/lists.c9
-rw-r--r--drivers/cpu/Kconfig8
-rw-r--r--drivers/cpu/Makefile7
-rw-r--r--drivers/cpu/cpu-uclass.c61
-rw-r--r--drivers/ddr/mvebu/ddr3_axp.h2
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/axp_gpio.c186
-rw-r--r--drivers/gpio/sunxi_gpio.c104
-rw-r--r--drivers/misc/smsc_lpc47m.c3
-rw-r--r--drivers/mmc/bcm2835_sdhci.c8
-rw-r--r--drivers/mmc/dw_mmc.c2
-rw-r--r--drivers/mmc/fsl_esdhc.c6
-rw-r--r--drivers/mmc/kona_sdhci.c1
-rw-r--r--drivers/mmc/mmc.c93
-rw-r--r--drivers/mmc/mvebu_mmc.c2
-rw-r--r--drivers/mmc/mxsmmc.c3
-rw-r--r--drivers/mmc/omap_hsmmc.c3
-rw-r--r--drivers/mmc/s3c_sdi.c2
-rw-r--r--drivers/mmc/s5p_sdhci.c1
-rw-r--r--drivers/mmc/sdhci.c2
-rw-r--r--drivers/mmc/sh_mmcif.c2
-rw-r--r--drivers/mmc/sunxi_mmc.c12
-rw-r--r--drivers/mmc/tegra_mmc.c14
-rw-r--r--drivers/mmc/zynq_sdhci.c2
-rw-r--r--drivers/net/sunxi_emac.c260
-rw-r--r--drivers/pci/pci_rom.c24
-rw-r--r--drivers/power/axp209.c64
-rw-r--r--drivers/power/axp221.c236
-rw-r--r--drivers/serial/arm_dcc.c4
-rw-r--r--drivers/usb/host/ehci-sunxi.c46
-rw-r--r--drivers/usb/musb-new/musb_regs.h5
-rw-r--r--drivers/usb/musb-new/musb_uboot.c6
-rw-r--r--drivers/usb/musb-new/sunxi.c43
-rw-r--r--drivers/video/sunxi_display.c29
37 files changed, 724 insertions, 533 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 941aa0c..1f40887 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -2,6 +2,8 @@ menu "Device Drivers"
source "drivers/core/Kconfig"
+source "drivers/cpu/Kconfig"
+
source "drivers/demo/Kconfig"
source "drivers/pci/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5ef58c0..405b64b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_DM_DEMO) += demo/
obj-$(CONFIG_BIOSEMU) += bios_emulator/
obj-y += block/
obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
+obj-$(CONFIG_CPU) += cpu/
obj-y += crypto/
obj-$(CONFIG_FPGA) += fpga/
obj-y += hwmon/
diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c
index 7ea5fa6..dec6230 100644
--- a/drivers/bios_emulator/atibios.c
+++ b/drivers/bios_emulator/atibios.c
@@ -502,7 +502,8 @@ int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
*/
if (clean_up) {
BE_exit();
- if (vga_info->BIOSImage)
+ if (vga_info->BIOSImage &&
+ (u32)(vga_info->BIOSImage) != 0xc0000)
free(vga_info->BIOSImage);
free(vga_info);
vga_info = NULL;
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 647e390..0c49d99 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -74,6 +74,13 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
int device_bind_driver(struct udevice *parent, const char *drv_name,
const char *dev_name, struct udevice **devp)
{
+ return device_bind_driver_to_node(parent, drv_name, dev_name, -1, devp);
+}
+
+int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
+ const char *dev_name, int node,
+ struct udevice **devp)
+{
struct driver *drv;
int ret;
@@ -82,7 +89,7 @@ int device_bind_driver(struct udevice *parent, const char *drv_name,
printf("Cannot find driver '%s'\n", drv_name);
return -ENOENT;
}
- ret = device_bind(parent, drv, dev_name, NULL, -1, devp);
+ ret = device_bind(parent, drv, dev_name, NULL, node, devp);
if (ret) {
printf("Cannot create device named '%s' (err=%d)\n",
dev_name, ret);
diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig
new file mode 100644
index 0000000..0d1424d
--- /dev/null
+++ b/drivers/cpu/Kconfig
@@ -0,0 +1,8 @@
+config CPU
+ bool "Enable CPU drivers using Driver Model"
+ help
+ This allows drivers to be provided for CPUs and their type to be
+ specified in the board's device tree. For boards which support
+ multiple CPUs, then normally have to be set up in U-Boot so that
+ they can work correctly in the OS. This provides a framework for
+ finding out information about available CPUs and making changes.
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
new file mode 100644
index 0000000..8710160
--- /dev/null
+++ b/drivers/cpu/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+obj-$(CONFIG_CPU) += cpu-uclass.o
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
new file mode 100644
index 0000000..ab18ee2
--- /dev/null
+++ b/drivers/cpu/cpu-uclass.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+int cpu_get_desc(struct udevice *dev, char *buf, int size)
+{
+ struct cpu_ops *ops = cpu_get_ops(dev);
+
+ if (!ops->get_desc)
+ return -ENOSYS;
+
+ return ops->get_desc(dev, buf, size);
+}
+
+int cpu_get_info(struct udevice *dev, struct cpu_info *info)
+{
+ struct cpu_ops *ops = cpu_get_ops(dev);
+
+ if (!ops->get_desc)
+ return -ENOSYS;
+
+ return ops->get_info(dev, info);
+}
+
+U_BOOT_DRIVER(cpu_bus) = {
+ .name = "cpu_bus",
+ .id = UCLASS_SIMPLE_BUS,
+ .per_child_platdata_auto_alloc_size = sizeof(struct cpu_platdata),
+};
+
+static int uclass_cpu_init(struct uclass *uc)
+{
+ struct udevice *dev;
+ int node;
+ int ret;
+
+ node = fdt_path_offset(gd->fdt_blob, "/cpus");
+ if (node < 0)
+ return 0;
+
+ ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
+ &dev);
+
+ return ret;
+}
+
+UCLASS_DRIVER(cpu) = {
+ .id = UCLASS_CPU,
+ .name = "cpu",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+ .init = uclass_cpu_init,
+};
diff --git a/drivers/ddr/mvebu/ddr3_axp.h b/drivers/ddr/mvebu/ddr3_axp.h
index bf65f6b..d9e33f7 100644
--- a/drivers/ddr/mvebu/ddr3_axp.h
+++ b/drivers/ddr/mvebu/ddr3_axp.h
@@ -35,7 +35,7 @@
#define ECC_SUPPORT
#define NEW_FABRIC_TWSI_ADDR 0x4E
-#ifdef DB_784MP_GP
+#ifdef CONFIG_DB_784MP_GP
#define BUS_WIDTH_ECC_TWSI_ADDR 0x4E
#else
#define BUS_WIDTH_ECC_TWSI_ADDR 0x4F
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index fb40e09..ba9efe8 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,6 +7,7 @@
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
+obj-$(CONFIG_AXP_GPIO) += axp_gpio.o
endif
/* TODO(sjg@chromium.org): Only tegra supports driver model in SPL */
ifdef CONFIG_TEGRA_GPIO
diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c
new file mode 100644
index 0000000..2e97cc3
--- /dev/null
+++ b/drivers/gpio/axp_gpio.c
@@ -0,0 +1,186 @@
+/*
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * X-Powers AXP Power Management ICs gpio driver
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pmic_bus.h>
+#include <asm/gpio.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)
+{
+ switch (pin) {
+ case 0: return AXP_GPIO0_CTRL;
+ case 1: return AXP_GPIO1_CTRL;
+#ifdef AXP_GPIO2_CTRL
+ case 2: return AXP_GPIO2_CTRL;
+#endif
+#ifdef AXP_GPIO3_CTRL
+ case 3: return AXP_GPIO3_CTRL;
+#endif
+ }
+ return 0;
+}
+
+static int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
+{
+ u8 reg;
+
+ switch (pin) {
+#ifndef CONFIG_AXP152_POWER /* NA on axp152 */
+ case SUNXI_GPIO_AXP0_VBUS_DETECT:
+ return 0;
+#endif
+ default:
+ reg = axp_get_gpio_ctrl_reg(pin);
+ if (reg == 0)
+ return -EINVAL;
+
+ return pmic_bus_write(reg, AXP_GPIO_CTRL_INPUT);
+ }
+}
+
+static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
+ int val)
+{
+ __maybe_unused int ret;
+ u8 reg;
+
+ switch (pin) {
+#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
+ case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+ ret = pmic_bus_clrbits(AXP221_MISC_CTRL,
+ AXP221_MISC_CTRL_N_VBUSEN_FUNC);
+ if (ret)
+ return ret;
+
+ return axp_gpio_set_value(dev, pin, val);
+#endif
+ default:
+ reg = axp_get_gpio_ctrl_reg(pin);
+ if (reg == 0)
+ return -EINVAL;
+
+ return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
+ AXP_GPIO_CTRL_OUTPUT_LOW);
+ }
+}
+
+static int axp_gpio_get_value(struct udevice *dev, unsigned pin)
+{
+ u8 reg, val, mask;
+ int ret;
+
+ switch (pin) {
+#ifndef CONFIG_AXP152_POWER /* NA on axp152 */
+ case SUNXI_GPIO_AXP0_VBUS_DETECT:
+ ret = pmic_bus_read(AXP_POWER_STATUS, &val);
+ mask = AXP_POWER_STATUS_VBUS_PRESENT;
+ break;
+#endif
+#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
+ case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+ ret = pmic_bus_read(AXP221_VBUS_IPSOUT, &val);
+ mask = AXP221_VBUS_IPSOUT_DRIVEBUS;
+ break;
+#endif
+ default:
+ reg = axp_get_gpio_ctrl_reg(pin);
+ if (reg == 0)
+ return -EINVAL;
+
+ ret = pmic_bus_read(AXP_GPIO_STATE, &val);
+ mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
+ }
+ if (ret)
+ return ret;
+
+ return (val & mask) ? 1 : 0;
+}
+
+static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
+{
+ u8 reg;
+
+ switch (pin) {
+#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
+ case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+ if (val)
+ return pmic_bus_setbits(AXP221_VBUS_IPSOUT,
+ AXP221_VBUS_IPSOUT_DRIVEBUS);
+ else
+ return pmic_bus_clrbits(AXP221_VBUS_IPSOUT,
+ AXP221_VBUS_IPSOUT_DRIVEBUS);
+#endif
+ default:
+ reg = axp_get_gpio_ctrl_reg(pin);
+ if (reg == 0)
+ return -EINVAL;
+
+ return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
+ AXP_GPIO_CTRL_OUTPUT_LOW);
+ }
+}
+
+static const struct dm_gpio_ops gpio_axp_ops = {
+ .direction_input = axp_gpio_direction_input,
+ .direction_output = axp_gpio_direction_output,
+ .get_value = axp_gpio_get_value,
+ .set_value = axp_gpio_set_value,
+};
+
+static int gpio_axp_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ /* Tell the uclass how many GPIOs we have */
+ uc_priv->bank_name = strdup(SUNXI_GPIO_AXP0_PREFIX);
+ uc_priv->gpio_count = SUNXI_GPIO_AXP0_GPIO_COUNT;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(gpio_axp) = {
+ .name = "gpio_axp",
+ .id = UCLASS_GPIO,
+ .ops = &gpio_axp_ops,
+ .probe = gpio_axp_probe,
+};
+
+int axp_gpio_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = pmic_bus_init();
+ if (ret)
+ return ret;
+
+ /* There is no devicetree support for the axp yet, so bind directly */
+ ret = device_bind_driver(dm_root(), "gpio_axp", "AXP-gpio", &dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index cf5c624..f988130 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -15,15 +15,10 @@
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
+#include <asm/arch/gpio.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <dm/device-internal.h>
-#ifdef CONFIG_AXP209_POWER
-#include <axp209.h>
-#endif
-#ifdef CONFIG_AXP221_POWER
-#include <axp221.h>
-#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -79,10 +74,6 @@ int gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio)
{
-#ifdef AXP_GPIO
- if (gpio >= SUNXI_GPIO_AXP0_START)
- return axp_gpio_direction_input(gpio - SUNXI_GPIO_AXP0_START);
-#endif
sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
return 0;
@@ -90,11 +81,6 @@ int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value)
{
-#ifdef AXP_GPIO
- if (gpio >= SUNXI_GPIO_AXP0_START)
- return axp_gpio_direction_output(gpio - SUNXI_GPIO_AXP0_START,
- value);
-#endif
sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
return sunxi_gpio_output(gpio, value);
@@ -102,36 +88,14 @@ int gpio_direction_output(unsigned gpio, int value)
int gpio_get_value(unsigned gpio)
{
-#ifdef AXP_GPIO
- if (gpio >= SUNXI_GPIO_AXP0_START)
- return axp_gpio_get_value(gpio - SUNXI_GPIO_AXP0_START);
-#endif
return sunxi_gpio_input(gpio);
}
int gpio_set_value(unsigned gpio, int value)
{
-#ifdef AXP_GPIO
- if (gpio >= SUNXI_GPIO_AXP0_START)
- return axp_gpio_set_value(gpio - SUNXI_GPIO_AXP0_START, value);
-#endif
return sunxi_gpio_output(gpio, value);
}
-int sunxi_name_to_gpio_bank(const char *name)
-{
- int group = 0;
-
- if (*name == 'P' || *name == 'p')
- name++;
- if (*name >= 'A') {
- group = *name - (*name > 'a' ? 'a' : 'A');
- return group;
- }
-
- return -1;
-}
-
int sunxi_name_to_gpio(const char *name)
{
int group = 0;
@@ -139,21 +103,6 @@ int sunxi_name_to_gpio(const char *name)
long pin;
char *eptr;
-#ifdef AXP_GPIO
- if (strncasecmp(name, "AXP0-", 5) == 0) {
- name += 5;
- if (strcmp(name, "VBUS-DETECT") == 0)
- return SUNXI_GPIO_AXP0_START +
- SUNXI_GPIO_AXP0_VBUS_DETECT;
- if (strcmp(name, "VBUS-ENABLE") == 0)
- return SUNXI_GPIO_AXP0_START +
- SUNXI_GPIO_AXP0_VBUS_ENABLE;
- pin = simple_strtol(name, &eptr, 10);
- if (!*name || *eptr)
- return -1;
- return SUNXI_GPIO_AXP0_START + pin;
- }
-#endif
if (*name == 'P' || *name == 'p')
name++;
if (*name >= 'A') {
@@ -171,7 +120,44 @@ int sunxi_name_to_gpio(const char *name)
}
#endif
+int sunxi_name_to_gpio_bank(const char *name)
+{
+ int group = 0;
+
+ if (*name == 'P' || *name == 'p')
+ name++;
+ if (*name >= 'A') {
+ group = *name - (*name > 'a' ? 'a' : 'A');
+ return group;
+ }
+
+ return -1;
+}
+
#ifdef CONFIG_DM_GPIO
+/* TODO(sjg@chromium.org): Remove this function and use device tree */
+int sunxi_name_to_gpio(const char *name)
+{
+ unsigned int gpio;
+ int ret;
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
+ char lookup[8];
+
+ if (strcasecmp(name, "AXP0-VBUS-DETECT") == 0) {
+ sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d",
+ SUNXI_GPIO_AXP0_VBUS_DETECT);
+ name = lookup;
+ } else if (strcasecmp(name, "AXP0-VBUS-ENABLE") == 0) {
+ sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d",
+ SUNXI_GPIO_AXP0_VBUS_ENABLE);
+ name = lookup;
+ }
+#endif
+ ret = gpio_lookup_name(name, NULL, NULL, &gpio);
+
+ return ret ? ret : gpio;
+}
+
static int sunxi_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
@@ -249,10 +235,11 @@ static char *gpio_bank_name(int bank)
{
char *name;
- name = malloc(2);
+ name = malloc(3);
if (name) {
- name[0] = 'A' + bank;
- name[1] = '\0';
+ name[0] = 'P';
+ name[1] = 'A' + bank;
+ name[2] = '\0';
}
return name;
@@ -310,7 +297,14 @@ static int gpio_sunxi_bind(struct udevice *parent)
}
static const struct udevice_id sunxi_gpio_ids[] = {
+ { .compatible = "allwinner,sun4i-a10-pinctrl" },
+ { .compatible = "allwinner,sun5i-a10s-pinctrl" },
+ { .compatible = "allwinner,sun5i-a13-pinctrl" },
+ { .compatible = "allwinner,sun6i-a31-pinctrl" },
+ { .compatible = "allwinner,sun6i-a31s-pinctrl" },
{ .compatible = "allwinner,sun7i-a20-pinctrl" },
+ { .compatible = "allwinner,sun8i-a23-pinctrl" },
+ { .compatible = "allwinner,sun9i-a80-pinctrl" },
{ }
};
diff --git a/drivers/misc/smsc_lpc47m.c b/drivers/misc/smsc_lpc47m.c
index d51f8e3..1e50d5b 100644
--- a/drivers/misc/smsc_lpc47m.c
+++ b/drivers/misc/smsc_lpc47m.c
@@ -22,12 +22,13 @@ static void pnp_exit_conf_state(u16 dev)
outb(0xaa, port);
}
-void lpc47m_enable_serial(u16 dev, u16 iobase)
+void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq)
{
pnp_enter_conf_state(dev);
pnp_set_logical_device(dev);
pnp_set_enable(dev, 0);
pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+ pnp_set_irq(dev, PNP_IDX_IRQ0, irq);
pnp_set_enable(dev, 1);
pnp_exit_conf_state(dev);
}
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index 4ec2968..078ef05 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -69,11 +69,11 @@ static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
* (Which is just as well - otherwise we'd have to nobble the DMA engine
* too)
*/
- while (get_timer_us(bcm_host->last_write) < bcm_host->twoticks_delay)
+ while (get_timer(bcm_host->last_write) < bcm_host->twoticks_delay)
;
writel(val, host->ioaddr + reg);
- bcm_host->last_write = get_timer_us(0);
+ bcm_host->last_write = get_timer(0);
}
static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)
@@ -154,9 +154,9 @@ int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
struct bcm2835_sdhci_host *bcm_host;
struct sdhci_host *host;
- bcm_host = malloc(sizeof(*bcm_host));
+ bcm_host = calloc(1, sizeof(*bcm_host));
if (!bcm_host) {
- printf("sdhci_host malloc fail!\n");
+ printf("sdhci_host calloc fail!\n");
return 1;
}
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 76fa0b0..53a8aca 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -388,7 +388,7 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
host->cfg.host_caps |= MMC_MODE_4BIT;
host->cfg.host_caps &= ~MMC_MODE_8BIT;
}
- host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
+ host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c690a97..c4719e6 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -387,9 +387,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Workaround for ESDHC errata ENGcm03648 */
if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
- int timeout = 2500;
+ int timeout = 6000;
- /* Poll on DATA0 line for cmd with busy signal for 250 ms */
+ /* Poll on DATA0 line for cmd with busy signal for 600 ms */
while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
PRSSTAT_DAT0)) {
udelay(100);
@@ -688,7 +688,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
return -1;
}
- cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+ cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
#endif
diff --git a/drivers/mmc/kona_sdhci.c b/drivers/mmc/kona_sdhci.c
index f804f4c..3653d00 100644
--- a/drivers/mmc/kona_sdhci.c
+++ b/drivers/mmc/kona_sdhci.c
@@ -121,7 +121,6 @@ int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
host->name = "kona-sdhci";
host->ioaddr = reg_base;
host->quirks = quirks;
- host->host_caps = MMC_MODE_HC;
if (init_kona_mmc_core(host)) {
free(host);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index dc32aec..79e6fee 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -118,7 +118,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
if (!mmc_host_is_spi(mmc))
cmd.cmdarg = mmc->rca << 16;
- do {
+ while (1) {
err = mmc_send_cmd(mmc, &cmd, NULL);
if (!err) {
if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
@@ -135,9 +135,11 @@ int mmc_send_status(struct mmc *mmc, int timeout)
} else if (--retries < 0)
return err;
- udelay(1000);
+ if (timeout-- <= 0)
+ break;
- } while (timeout--);
+ udelay(1000);
+ }
#ifdef CONFIG_MMC_TRACE
status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
@@ -291,7 +293,7 @@ static int sd_send_op_cond(struct mmc *mmc)
int err;
struct mmc_cmd cmd;
- do {
+ while (1) {
cmd.cmdidx = MMC_CMD_APP_CMD;
cmd.resp_type = MMC_RSP_R1;
cmd.cmdarg = 0;
@@ -322,11 +324,14 @@ static int sd_send_op_cond(struct mmc *mmc)
if (err)
return err;
- udelay(1000);
- } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+ if (cmd.response[0] & OCR_BUSY)
+ break;
- if (timeout <= 0)
- return UNUSABLE_ERR;
+ if (timeout-- <= 0)
+ return UNUSABLE_ERR;
+
+ udelay(1000);
+ }
if (mmc->version != SD_VERSION_2)
mmc->version = SD_VERSION_1_0;
@@ -350,51 +355,46 @@ static int sd_send_op_cond(struct mmc *mmc)
return 0;
}
-/* We pass in the cmd since otherwise the init seems to fail */
-static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
- int use_arg)
+static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
{
+ struct mmc_cmd cmd;
int err;
- cmd->cmdidx = MMC_CMD_SEND_OP_COND;
- cmd->resp_type = MMC_RSP_R3;
- cmd->cmdarg = 0;
- if (use_arg && !mmc_host_is_spi(mmc)) {
- cmd->cmdarg =
+ cmd.cmdidx = MMC_CMD_SEND_OP_COND;
+ cmd.resp_type = MMC_RSP_R3;
+ cmd.cmdarg = 0;
+ if (use_arg && !mmc_host_is_spi(mmc))
+ cmd.cmdarg = OCR_HCS |
(mmc->cfg->voltages &
- (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
- (mmc->op_cond_response & OCR_ACCESS_MODE);
+ (mmc->ocr & OCR_VOLTAGE_MASK)) |
+ (mmc->ocr & OCR_ACCESS_MODE);
- if (mmc->cfg->host_caps & MMC_MODE_HC)
- cmd->cmdarg |= OCR_HCS;
- }
- err = mmc_send_cmd(mmc, cmd, NULL);
+ err = mmc_send_cmd(mmc, &cmd, NULL);
if (err)
return err;
- mmc->op_cond_response = cmd->response[0];
+ mmc->ocr = cmd.response[0];
return 0;
}
static int mmc_send_op_cond(struct mmc *mmc)
{
- struct mmc_cmd cmd;
int err, i;
/* Some cards seem to need this */
mmc_go_idle(mmc);
/* Asking to the card its capabilities */
- mmc->op_cond_pending = 1;
for (i = 0; i < 2; i++) {
- err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
+ err = mmc_send_op_cond_iter(mmc, i != 0);
if (err)
return err;
/* exit if not busy (flag seems to be inverted) */
- if (mmc->op_cond_response & OCR_BUSY)
- return 0;
+ if (mmc->ocr & OCR_BUSY)
+ break;
}
- return IN_PROGRESS;
+ mmc->op_cond_pending = 1;
+ return 0;
}
static int mmc_complete_op_cond(struct mmc *mmc)
@@ -405,15 +405,19 @@ static int mmc_complete_op_cond(struct mmc *mmc)
int err;
mmc->op_cond_pending = 0;
- start = get_timer(0);
- do {
- err = mmc_send_op_cond_iter(mmc, &cmd, 1);
- if (err)
- return err;
- if (get_timer(start) > timeout)
- return UNUSABLE_ERR;
- udelay(100);
- } while (!(mmc->op_cond_response & OCR_BUSY));
+ if (!(mmc->ocr & OCR_BUSY)) {
+ start = get_timer(0);
+ while (1) {
+ err = mmc_send_op_cond_iter(mmc, 1);
+ if (err)
+ return err;
+ if (mmc->ocr & OCR_BUSY)
+ break;
+ if (get_timer(start) > timeout)
+ return UNUSABLE_ERR;
+ udelay(100);
+ }
+ }
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
@@ -424,10 +428,11 @@ static int mmc_complete_op_cond(struct mmc *mmc)
if (err)
return err;
+
+ mmc->ocr = cmd.response[0];
}
mmc->version = MMC_VERSION_UNKNOWN;
- mmc->ocr = cmd.response[0];
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
mmc->rca = 1;
@@ -1622,7 +1627,7 @@ int mmc_start_init(struct mmc *mmc)
if (err == TIMEOUT) {
err = mmc_send_op_cond(mmc);
- if (err && err != IN_PROGRESS) {
+ if (err) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("Card did not respond to voltage select!\n");
#endif
@@ -1630,7 +1635,7 @@ int mmc_start_init(struct mmc *mmc)
}
}
- if (err == IN_PROGRESS)
+ if (!err)
mmc->init_in_progress = 1;
return err;
@@ -1640,6 +1645,7 @@ static int mmc_complete_init(struct mmc *mmc)
{
int err = 0;
+ mmc->init_in_progress = 0;
if (mmc->op_cond_pending)
err = mmc_complete_op_cond(mmc);
@@ -1649,13 +1655,12 @@ static int mmc_complete_init(struct mmc *mmc)
mmc->has_init = 0;
else
mmc->has_init = 1;
- mmc->init_in_progress = 0;
return err;
}
int mmc_init(struct mmc *mmc)
{
- int err = IN_PROGRESS;
+ int err = 0;
unsigned start;
if (mmc->has_init)
@@ -1666,7 +1671,7 @@ int mmc_init(struct mmc *mmc)
if (!mmc->init_in_progress)
err = mmc_start_init(mmc);
- if (!err || err == IN_PROGRESS)
+ if (!err)
err = mmc_complete_init(mmc);
debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
return err;
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 8ca0904..056aef5 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -418,7 +418,7 @@ static struct mmc_config mvebu_mmc_cfg = {
.f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
.f_max = MVEBU_MMC_CLOCKRATE_MAX,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
- .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |
+ .host_caps = MMC_MODE_4BIT | MMC_MODE_HS |
MMC_MODE_HS_52MHz,
.part_type = PART_TYPE_DOS,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 2fa4eee..31fb3ab 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -405,8 +405,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
- MMC_MODE_HS_52MHz | MMC_MODE_HS |
- MMC_MODE_HC;
+ MMC_MODE_HS_52MHz | MMC_MODE_HS;
/*
* SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index dc725cb..8238a7e 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -651,8 +651,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
if (priv_data == NULL)
return -1;
- host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
- MMC_MODE_HC;
+ host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
switch (dev_index) {
case 0:
diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c
index 1b5b705..02d1138 100644
--- a/drivers/mmc/s3c_sdi.c
+++ b/drivers/mmc/s3c_sdi.c
@@ -298,7 +298,7 @@ int s3cmmc_initialize(bd_t *bis, int (*getcd)(struct mmc *),
cfg->name = "S3C MMC";
cfg->ops = &s3cmmc_ops;
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
- cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HC | MMC_MODE_HS;
+ cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;
cfg->f_min = 400000;
cfg->f_max = get_PCLK() / 2;
cfg->b_max = 0x80;
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 0eec731..8e1968a 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -76,7 +76,6 @@ static int s5p_sdhci_core_init(struct sdhci_host *host)
host->set_control_reg = &s5p_sdhci_set_control_reg;
host->set_clock = set_mmc_clk;
- host->host_caps = MMC_MODE_HC;
if (host->bus_width == 8)
host->host_caps |= MMC_MODE_8BIT;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 5332e61..75556a3 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -213,6 +213,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
SDHCI_BLOCK_SIZE);
sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
+ } else if (cmd->resp_type & MMC_RSP_BUSY) {
+ sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
}
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c
index 76ba93b..f92cf00 100644
--- a/drivers/mmc/sh_mmcif.c
+++ b/drivers/mmc/sh_mmcif.c
@@ -577,7 +577,7 @@ static struct mmc_config sh_mmcif_cfg = {
.name = DRIVER_NAME,
.ops = &sh_mmcif_ops,
.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
- MMC_MODE_8BIT | MMC_MODE_HC,
+ MMC_MODE_8BIT,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
};
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 2233545..bb08147 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -9,6 +9,7 @@
*/
#include <common.h>
+#include <errno.h>
#include <malloc.h>
#include <mmc.h>
#include <asm/io.h>
@@ -37,7 +38,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no)
case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN);
case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN);
}
- return -1;
+ return -EINVAL;
}
static int mmc_resource_init(int sdc_no)
@@ -72,7 +73,7 @@ static int mmc_resource_init(int sdc_no)
mmchost->mmc_no = sdc_no;
cd_pin = sunxi_mmc_getcd_gpio(sdc_no);
- if (cd_pin != -1) {
+ if (cd_pin >= 0) {
ret = gpio_request(cd_pin, "mmc_cd");
if (!ret)
ret = gpio_direction_input(cd_pin);
@@ -151,8 +152,7 @@ static int mmc_clk_io_on(int sdc_no)
/* config ahb clock */
setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
- defined(CONFIG_MACH_SUN9I)
+#ifdef CONFIG_SUNXI_GEN_SUN6I
/* unassert reset */
setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
#endif
@@ -425,7 +425,7 @@ static int sunxi_mmc_getcd(struct mmc *mmc)
int cd_pin;
cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no);
- if (cd_pin == -1)
+ if (cd_pin < 0)
return 1;
return !gpio_get_value(cd_pin);
@@ -449,7 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->host_caps = MMC_MODE_4BIT;
- cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
cfg->f_min = 400000;
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 2cd8cf1..d555692 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -528,7 +528,7 @@ static const struct mmc_ops tegra_mmc_ops = {
.getcd = tegra_mmc_getcd,
};
-static int do_mmc_init(int dev_index)
+static int do_mmc_init(int dev_index, bool removable)
{
struct mmc_host *host;
struct mmc *mmc;
@@ -559,7 +559,7 @@ static int do_mmc_init(int dev_index)
host->cfg.host_caps |= MMC_MODE_8BIT;
if (host->width >= 4)
host->cfg.host_caps |= MMC_MODE_4BIT;
- host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+ host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
/*
* min freq is for card identification, and is the highest
@@ -573,6 +573,7 @@ static int do_mmc_init(int dev_index)
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
mmc = mmc_create(&host->cfg, host);
+ mmc->block_dev.removable = removable;
if (mmc == NULL)
return -1;
@@ -586,7 +587,8 @@ static int do_mmc_init(int dev_index)
* @param node Device index (0-3)
* @param host Structure to fill in (reg, width, mmc_id)
*/
-static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
+static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
+ bool *removablep)
{
debug("%s: node = %d\n", __func__, node);
@@ -619,6 +621,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
GPIOD_IS_IN);
gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
&host->pwr_gpio, GPIOD_IS_OUT);
+ *removablep = !fdtdec_get_bool(blob, node, "non-removable");
debug("%s: found controller at %p, width = %d, periph_id = %d\n",
__func__, host->reg, host->width, host->mmc_id);
@@ -636,6 +639,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
static int process_nodes(const void *blob, int node_list[], int count)
{
struct mmc_host *host;
+ bool removable;
int i, node;
debug("%s: count = %d\n", __func__, count);
@@ -649,11 +653,11 @@ static int process_nodes(const void *blob, int node_list[], int count)
host = &mmc_host[i];
host->id = i;
- if (mmc_get_config(blob, node, host)) {
+ if (mmc_get_config(blob, node, host, &removable)) {
printf("%s: failed to decode dev %d\n", __func__, i);
return -1;
}
- do_mmc_init(i);
+ do_mmc_init(i, removable);
}
return 0;
}
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index d4f3882..971acbb 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -29,8 +29,6 @@ int zynq_sdhci_init(phys_addr_t regbase)
SDHCI_QUIRK_BROKEN_R1B;
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
- host->host_caps = MMC_MODE_HC;
-
add_sdhci(host, 52000000, 52000000 >> 9);
return 0;
}
diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
index 7b31f8c..e939bf2 100644
--- a/drivers/net/sunxi_emac.c
+++ b/drivers/net/sunxi_emac.c
@@ -7,6 +7,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/err.h>
#include <malloc.h>
#include <miiphy.h>
@@ -153,13 +154,16 @@ struct sunxi_sramc_regs {
#define EMAC_CRCERR (0x1 << 4)
#define EMAC_LENERR (0x3 << 5)
-#define DMA_CPU_TRRESHOLD 2000
+#define EMAC_RX_BUFSIZE 2000
struct emac_eth_dev {
- u32 speed;
- u32 duplex;
- u32 phy_configured;
+ struct emac_regs *regs;
+ struct mii_dev *bus;
+ struct phy_device *phydev;
int link_printed;
+#ifdef CONFIG_DM_ETH
+ uchar rx_buf[EMAC_RX_BUFSIZE];
+#endif
};
struct emac_rxhdr {
@@ -195,11 +199,10 @@ static void emac_outblk_32bit(void *reg, void *data, int count)
}
/* Read a word from phyxcer */
-static int emac_phy_read(const char *devname, unsigned char addr,
- unsigned char reg, unsigned short *value)
+static int emac_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
{
- struct eth_device *dev = eth_get_dev_by_name(devname);
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
+ struct emac_eth_dev *priv = bus->priv;
+ struct emac_regs *regs = priv->regs;
/* issue the phy address and reg */
writel(addr << 8 | reg, &regs->mac_madr);
@@ -213,18 +216,16 @@ static int emac_phy_read(const char *devname, unsigned char addr,
/* push down the phy io line */
writel(0x0, &regs->mac_mcmd);
- /* and write data */
- *value = readl(&regs->mac_mrdd);
-
- return 0;
+ /* And read data */
+ return readl(&regs->mac_mrdd);
}
/* Write a word to phyxcer */
-static int emac_phy_write(const char *devname, unsigned char addr,
- unsigned char reg, unsigned short value)
+static int emac_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 value)
{
- struct eth_device *dev = eth_get_dev_by_name(devname);
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
+ struct emac_eth_dev *priv = bus->priv;
+ struct emac_regs *regs = priv->regs;
/* issue the phy address and reg */
writel(addr << 8 | reg, &regs->mac_madr);
@@ -244,12 +245,44 @@ static int emac_phy_write(const char *devname, unsigned char addr,
return 0;
}
-static void emac_setup(struct eth_device *dev)
+static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
+{
+ int ret, mask = 0xffffffff;
+
+#ifdef CONFIG_PHY_ADDR
+ mask = 1 << CONFIG_PHY_ADDR;
+#endif
+
+ priv->bus = mdio_alloc();
+ if (!priv->bus) {
+ printf("Failed to allocate MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ priv->bus->read = emac_mdio_read;
+ priv->bus->write = emac_mdio_write;
+ priv->bus->priv = priv;
+ strcpy(priv->bus->name, "emac");
+
+ ret = mdio_register(priv->bus);
+ if (ret)
+ return ret;
+
+ priv->phydev = phy_find_by_mask(priv->bus, mask,
+ PHY_INTERFACE_MODE_MII);
+ if (!priv->phydev)
+ return -ENODEV;
+
+ phy_connect_dev(priv->phydev, dev);
+ phy_config(priv->phydev);
+
+ return 0;
+}
+
+static void emac_setup(struct emac_eth_dev *priv)
{
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
+ struct emac_regs *regs = priv->regs;
u32 reg_val;
- u16 phy_val;
- u32 duplex_flag;
/* Set up TX */
writel(EMAC_TX_SETUP, &regs->tx_mode);
@@ -262,12 +295,8 @@ static void emac_setup(struct eth_device *dev)
writel(EMAC_MAC_CTL0_SETUP, &regs->mac_ctl0);
/* Set MAC CTL1 */
- emac_phy_read(dev->name, 1, 0, &phy_val);
- debug("PHY SETUP, reg 0 value: %x\n", phy_val);
- duplex_flag = !!(phy_val & (1 << 8));
-
reg_val = 0;
- if (duplex_flag)
+ if (priv->phydev->duplex == DUPLEX_FULL)
reg_val = (0x1 << 0);
writel(EMAC_MAC_CTL1_SETUP | reg_val, &regs->mac_ctl1);
@@ -284,9 +313,9 @@ static void emac_setup(struct eth_device *dev)
writel(EMAC_MAC_MFL, &regs->mac_maxf);
}
-static void emac_reset(struct eth_device *dev)
+static void emac_reset(struct emac_eth_dev *priv)
{
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
+ struct emac_regs *regs = priv->regs;
debug("resetting device\n");
@@ -298,11 +327,10 @@ static void emac_reset(struct eth_device *dev)
udelay(200);
}
-static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd)
+static int _sunxi_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr)
{
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
- struct emac_eth_dev *priv = dev->priv;
- u16 phy_reg;
+ struct emac_regs *regs = priv->regs;
+ int ret;
/* Init EMAC */
@@ -320,41 +348,44 @@ static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd)
udelay(1);
/* Set up EMAC */
- emac_setup(dev);
+ emac_setup(priv);
- writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 |
- dev->enetaddr[2], &regs->mac_a1);
- writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 |
- dev->enetaddr[5], &regs->mac_a0);
+ writel(enetaddr[0] << 16 | enetaddr[1] << 8 | enetaddr[2],
+ &regs->mac_a1);
+ writel(enetaddr[3] << 16 | enetaddr[4] << 8 | enetaddr[5],
+ &regs->mac_a0);
mdelay(1);
- emac_reset(dev);
+ emac_reset(priv);
/* PHY POWER UP */
- emac_phy_read(dev->name, 1, 0, &phy_reg);
- emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11)));
- mdelay(1);
-
- emac_phy_read(dev->name, 1, 0, &phy_reg);
-
- priv->speed = miiphy_speed(dev->name, 0);
- priv->duplex = miiphy_duplex(dev->name, 0);
+ ret = phy_startup(priv->phydev);
+ if (ret) {
+ printf("Could not initialize PHY %s\n",
+ priv->phydev->dev->name);
+ return ret;
+ }
/* Print link status only once */
if (!priv->link_printed) {
printf("ENET Speed is %d Mbps - %s duplex connection\n",
- priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
+ priv->phydev->speed,
+ priv->phydev->duplex ? "FULL" : "HALF");
priv->link_printed = 1;
}
/* Set EMAC SPEED depend on PHY */
- clrsetbits_le32(&regs->mac_supp, 1 << 8,
- ((phy_reg & (0x1 << 13)) >> 13) << 8);
+ if (priv->phydev->speed == SPEED_100)
+ setbits_le32(&regs->mac_supp, 1 << 8);
+ else
+ clrbits_le32(&regs->mac_supp, 1 << 8);
/* Set duplex depend on phy */
- clrsetbits_le32(&regs->mac_ctl1, 1 << 0,
- ((phy_reg & (0x1 << 8)) >> 8) << 0);
+ if (priv->phydev->duplex == DUPLEX_FULL)
+ setbits_le32(&regs->mac_ctl1, 1 << 0);
+ else
+ clrbits_le32(&regs->mac_ctl1, 1 << 0);
/* Enable RX/TX */
setbits_le32(&regs->ctl, 0x7);
@@ -362,14 +393,9 @@ static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd)
return 0;
}
-static void sunxi_emac_eth_halt(struct eth_device *dev)
-{
- /* Nothing to do here */
-}
-
-static int sunxi_emac_eth_recv(struct eth_device *dev)
+static int _sunxi_emac_eth_recv(struct emac_eth_dev *priv, void *packet)
{
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
+ struct emac_regs *regs = priv->regs;
struct emac_rxhdr rxhdr;
u32 rxcount;
u32 reg_val;
@@ -387,7 +413,7 @@ static int sunxi_emac_eth_recv(struct eth_device *dev)
/* Had one stuck? */
rxcount = readl(&regs->rx_fbc);
if (!rxcount)
- return 0;
+ return -EAGAIN;
}
reg_val = readl(&regs->rx_io_data);
@@ -403,7 +429,7 @@ static int sunxi_emac_eth_recv(struct eth_device *dev)
/* Enable RX */
setbits_le32(&regs->ctl, 0x1 << 2);
- return 0;
+ return -EAGAIN;
}
/* A packet ready now
@@ -433,24 +459,21 @@ static int sunxi_emac_eth_recv(struct eth_device *dev)
/* Move data from EMAC */
if (good_packet) {
- if (rx_len > DMA_CPU_TRRESHOLD) {
+ if (rx_len > EMAC_RX_BUFSIZE) {
printf("Received packet is too big (len=%d)\n", rx_len);
- } else {
- emac_inblk_32bit((void *)&regs->rx_io_data,
- net_rx_packets[0], rx_len);
-
- /* Pass to upper layer */
- net_process_received_packet(net_rx_packets[0], rx_len);
- return rx_len;
+ return -EMSGSIZE;
}
+ emac_inblk_32bit((void *)&regs->rx_io_data, packet, rx_len);
+ return rx_len;
}
- return 0;
+ return -EIO; /* Bad packet */
}
-static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len)
+static int _sunxi_emac_eth_send(struct emac_eth_dev *priv, void *packet,
+ int len)
{
- struct emac_regs *regs = (struct emac_regs *)dev->iobase;
+ struct emac_regs *regs = priv->regs;
/* Select channel 0 */
writel(0, &regs->tx_ins);
@@ -467,31 +490,15 @@ static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len)
return 0;
}
-int sunxi_emac_initialize(void)
+static void sunxi_emac_board_setup(struct emac_eth_dev *priv)
{
struct sunxi_ccm_reg *const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_sramc_regs *sram =
(struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE;
- struct emac_regs *regs =
- (struct emac_regs *)SUNXI_EMAC_BASE;
- struct eth_device *dev;
- struct emac_eth_dev *priv;
+ struct emac_regs *regs = priv->regs;
int pin;
- dev = malloc(sizeof(*dev));
- if (dev == NULL)
- return -ENOMEM;
-
- priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev));
- if (!priv) {
- free(dev);
- return -ENOMEM;
- }
-
- memset(dev, 0, sizeof(*dev));
- memset(priv, 0, sizeof(struct emac_eth_dev));
-
/* Map SRAM to EMAC */
setbits_le32(&sram->ctrl1, 0x5 << 2);
@@ -504,18 +511,77 @@ int sunxi_emac_initialize(void)
/* Set MII clock */
clrsetbits_le32(&regs->mac_mcfg, 0xf << 2, 0xd << 2);
+}
+
+static int sunxi_emac_eth_start(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ return _sunxi_emac_eth_init(dev->priv, pdata->enetaddr);
+}
+
+static int sunxi_emac_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct emac_eth_dev *priv = dev_get_priv(dev);
- dev->iobase = (int)regs;
- dev->priv = priv;
- dev->init = sunxi_emac_eth_init;
- dev->halt = sunxi_emac_eth_halt;
- dev->send = sunxi_emac_eth_send;
- dev->recv = sunxi_emac_eth_recv;
- strcpy(dev->name, "emac");
+ return _sunxi_emac_eth_send(priv, packet, length);
+}
+
+static int sunxi_emac_eth_recv(struct udevice *dev, uchar **packetp)
+{
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+ int rx_len;
- eth_register(dev);
+ rx_len = _sunxi_emac_eth_recv(priv, priv->rx_buf);
+ *packetp = priv->rx_buf;
- miiphy_register(dev->name, emac_phy_read, emac_phy_write);
+ return rx_len;
+}
+
+static void sunxi_emac_eth_stop(struct udevice *dev)
+{
+ /* Nothing to do here */
+}
+
+static int sunxi_emac_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ priv->regs = (struct emac_regs *)pdata->iobase;
+ sunxi_emac_board_setup(priv);
+
+ return sunxi_emac_init_phy(priv, dev);
+}
+
+static const struct eth_ops sunxi_emac_eth_ops = {
+ .start = sunxi_emac_eth_start,
+ .send = sunxi_emac_eth_send,
+ .recv = sunxi_emac_eth_recv,
+ .stop = sunxi_emac_eth_stop,
+};
+
+static int sunxi_emac_eth_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ pdata->iobase = dev_get_addr(dev);
return 0;
}
+
+static const struct udevice_id sunxi_emac_eth_ids[] = {
+ { .compatible = "allwinner,sun4i-a10-emac" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_sunxi_emac) = {
+ .name = "eth_sunxi_emac",
+ .id = UCLASS_ETH,
+ .of_match = sunxi_emac_eth_ids,
+ .ofdata_to_platdata = sunxi_emac_eth_ofdata_to_platdata,
+ .probe = sunxi_emac_eth_probe,
+ .ops = &sunxi_emac_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct emac_eth_dev),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 48c0a77..37450c8 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -67,6 +67,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
struct pci_rom_data *rom_data;
u16 vendor, device;
u16 rom_vendor, rom_device;
+ u32 rom_class;
u32 vendev;
u32 mapped_vendev;
u32 rom_address;
@@ -125,20 +126,20 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
/* Continue anyway */
}
- debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n",
- rom_data->class_hi, rom_data->class_lo, rom_data->type);
+ rom_class = (le16_to_cpu(rom_data->class_hi) << 8) | rom_data->class_lo;
+ debug("PCI ROM image, Class Code %06x, Code Type %02x\n",
+ rom_class, rom_data->type);
- if (class != ((rom_data->class_hi << 8) | rom_data->class_lo)) {
- debug("Class Code mismatch ROM %08x, dev %08x\n",
- (rom_data->class_hi << 8) | rom_data->class_lo,
- class);
+ if (class != rom_class) {
+ debug("Class Code mismatch ROM %06x, dev %06x\n",
+ rom_class, class);
}
*hdrp = rom_header;
return 0;
}
-int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header,
+int pci_rom_load(struct pci_rom_header *rom_header,
struct pci_rom_header **ram_headerp)
{
struct pci_rom_data *rom_data;
@@ -232,17 +233,18 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
{
struct pci_rom_header *rom, *ram;
int vesa_mode = -1;
- uint16_t class;
+ uint class;
bool emulate;
int ret;
/* Only execute VGA ROMs */
- pci_read_config_word(dev, PCI_CLASS_DEVICE, &class);
- if ((class ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) {
+ pci_read_config_dword(dev, PCI_REVISION_ID, &class);
+ if (((class >> 16) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) {
debug("%s: Class %#x, should be %#x\n", __func__, class,
PCI_CLASS_DISPLAY_VGA);
return -ENODEV;
}
+ class >>= 8;
if (!should_load_oprom(dev))
return -ENXIO;
@@ -251,7 +253,7 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
if (ret)
return ret;
- ret = pci_rom_load(class, rom, &ram);
+ ret = pci_rom_load(rom, &ram);
if (ret)
return ret;
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index 1d7be49..5161bc1 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -155,67 +155,3 @@ int axp209_power_button(void)
return v & AXP209_IRQ5_PEK_DOWN;
}
-
-static u8 axp209_get_gpio_ctrl_reg(unsigned int pin)
-{
- switch (pin) {
- case 0: return AXP209_GPIO0_CTRL;
- case 1: return AXP209_GPIO1_CTRL;
- case 2: return AXP209_GPIO2_CTRL;
- case 3: return AXP209_GPIO3_CTRL;
- }
- return 0;
-}
-
-int axp_gpio_direction_input(unsigned int pin)
-{
- if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT)
- return 0;
-
- u8 reg = axp209_get_gpio_ctrl_reg(pin);
- /* GPIO3 is "special" */
- u8 val = (pin == 3) ? AXP209_GPIO3_INPUT : AXP209_GPIO_INPUT;
-
- return axp209_write(reg, val);
-}
-
-int axp_gpio_direction_output(unsigned int pin, unsigned int val)
-{
- u8 reg = axp209_get_gpio_ctrl_reg(pin);
-
- if (val) {
- val = (pin == 3) ? AXP209_GPIO3_OUTPUT_HIGH :
- AXP209_GPIO_OUTPUT_HIGH;
- } else {
- val = (pin == 3) ? AXP209_GPIO3_OUTPUT_LOW :
- AXP209_GPIO_OUTPUT_LOW;
- }
-
- return axp209_write(reg, val);
-}
-
-int axp_gpio_get_value(unsigned int pin)
-{
- u8 val, mask;
- int rc;
-
- if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) {
- rc = axp209_read(AXP209_POWER_STATUS, &val);
- mask = AXP209_POWER_STATUS_VBUS_USABLE;
- } else if (pin == 3) {
- rc = axp209_read(AXP209_GPIO3_CTRL, &val);
- mask = 1;
- } else {
- rc = axp209_read(AXP209_GPIO_STATE, &val);
- mask = 1 << (pin + 4);
- }
- if (rc)
- return rc;
-
- return (val & mask) ? 1 : 0;
-}
-
-int axp_gpio_set_value(unsigned int pin, unsigned int val)
-{
- return axp_gpio_direction_output(pin, val);
-}
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index dc3a7f1..7bbaec8 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -12,50 +12,10 @@
#include <common.h>
#include <errno.h>
-#include <asm/arch/p2wi.h>
-#include <asm/arch/rsb.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/pmic_bus.h>
#include <axp221.h>
-/*
- * The axp221 uses the p2wi bus, the axp223 is identical (for all registers
- * used sofar) but uses the rsb bus. These functions abstract this.
- */
-static int pmic_bus_init(void)
-{
-#ifdef CONFIG_MACH_SUN6I
- p2wi_init();
- return p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR,
- AXP221_INIT_DATA);
-#else
- int ret;
-
- ret = rsb_init();
- if (ret)
- return ret;
-
- return rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR);
-#endif
-}
-
-static int pmic_bus_read(const u8 addr, u8 *data)
-{
-#ifdef CONFIG_MACH_SUN6I
- return p2wi_read(addr, data);
-#else
- return rsb_read(AXP223_RUNTIME_ADDR, addr, data);
-#endif
-}
-
-static int pmic_bus_write(const u8 addr, u8 data)
-{
-#ifdef CONFIG_MACH_SUN6I
- return p2wi_write(addr, data);
-#else
- return rsb_write(AXP223_RUNTIME_ADDR, addr, data);
-#endif
-}
-
static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div)
{
if (mvolt < min)
@@ -66,52 +26,26 @@ static u8 axp221_mvolt_to_cfg(int mvolt, int min, int max, int div)
return (mvolt - min) / div;
}
-static int axp221_setbits(u8 reg, u8 bits)
-{
- int ret;
- u8 val;
-
- ret = pmic_bus_read(reg, &val);
- if (ret)
- return ret;
-
- val |= bits;
- return pmic_bus_write(reg, val);
-}
-
-static int axp221_clrbits(u8 reg, u8 bits)
-{
- int ret;
- u8 val;
-
- ret = pmic_bus_read(reg, &val);
- if (ret)
- return ret;
-
- val &= ~bits;
- return pmic_bus_write(reg, val);
-}
-
int axp221_set_dcdc1(unsigned int mvolt)
{
int ret;
u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC1_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC1_EN);
ret = pmic_bus_write(AXP221_DCDC1_CTRL, cfg);
if (ret)
return ret;
- ret = axp221_setbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DCDC1SW_EN);
+ ret = pmic_bus_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DCDC1SW_EN);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC1_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC1_EN);
}
int axp221_set_dcdc2(unsigned int mvolt)
@@ -120,15 +54,15 @@ int axp221_set_dcdc2(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC2_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC2_EN);
ret = pmic_bus_write(AXP221_DCDC2_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC2_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC2_EN);
}
int axp221_set_dcdc3(unsigned int mvolt)
@@ -137,15 +71,15 @@ int axp221_set_dcdc3(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC3_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC3_EN);
ret = pmic_bus_write(AXP221_DCDC3_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC3_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC3_EN);
}
int axp221_set_dcdc4(unsigned int mvolt)
@@ -154,15 +88,15 @@ int axp221_set_dcdc4(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC4_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC4_EN);
ret = pmic_bus_write(AXP221_DCDC4_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC4_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC4_EN);
}
int axp221_set_dcdc5(unsigned int mvolt)
@@ -171,15 +105,15 @@ int axp221_set_dcdc5(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC5_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC5_EN);
ret = pmic_bus_write(AXP221_DCDC5_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_DCDC5_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_DCDC5_EN);
}
int axp221_set_dldo1(unsigned int mvolt)
@@ -188,15 +122,15 @@ int axp221_set_dldo1(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO1_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO1_EN);
ret = pmic_bus_write(AXP221_DLDO1_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO1_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO1_EN);
}
int axp221_set_dldo2(unsigned int mvolt)
@@ -205,15 +139,15 @@ int axp221_set_dldo2(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO2_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO2_EN);
ret = pmic_bus_write(AXP221_DLDO2_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO2_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO2_EN);
}
int axp221_set_dldo3(unsigned int mvolt)
@@ -222,15 +156,15 @@ int axp221_set_dldo3(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO3_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO3_EN);
ret = pmic_bus_write(AXP221_DLDO3_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO3_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO3_EN);
}
int axp221_set_dldo4(unsigned int mvolt)
@@ -239,15 +173,15 @@ int axp221_set_dldo4(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO4_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO4_EN);
ret = pmic_bus_write(AXP221_DLDO4_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2,
- AXP221_OUTPUT_CTRL2_DLDO4_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL2,
+ AXP221_OUTPUT_CTRL2_DLDO4_EN);
}
int axp221_set_aldo1(unsigned int mvolt)
@@ -256,15 +190,15 @@ int axp221_set_aldo1(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_ALDO1_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_ALDO1_EN);
ret = pmic_bus_write(AXP221_ALDO1_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_ALDO1_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_ALDO1_EN);
}
int axp221_set_aldo2(unsigned int mvolt)
@@ -273,15 +207,15 @@ int axp221_set_aldo2(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_ALDO2_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_ALDO2_EN);
ret = pmic_bus_write(AXP221_ALDO2_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL1,
- AXP221_OUTPUT_CTRL1_ALDO2_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL1,
+ AXP221_OUTPUT_CTRL1_ALDO2_EN);
}
int axp221_set_aldo3(unsigned int mvolt)
@@ -290,15 +224,15 @@ int axp221_set_aldo3(unsigned int mvolt)
u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL3,
- AXP221_OUTPUT_CTRL3_ALDO3_EN);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL3,
+ AXP221_OUTPUT_CTRL3_ALDO3_EN);
ret = pmic_bus_write(AXP221_ALDO3_CTRL, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL3,
- AXP221_OUTPUT_CTRL3_ALDO3_EN);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL3,
+ AXP221_OUTPUT_CTRL3_ALDO3_EN);
}
int axp221_set_eldo(int eldo_num, unsigned int mvolt)
@@ -325,13 +259,13 @@ int axp221_set_eldo(int eldo_num, unsigned int mvolt)
}
if (mvolt == 0)
- return axp221_clrbits(AXP221_OUTPUT_CTRL2, bits);
+ return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, bits);
ret = pmic_bus_write(addr, cfg);
if (ret)
return ret;
- return axp221_setbits(AXP221_OUTPUT_CTRL2, bits);
+ return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, bits);
}
int axp221_init(void)
@@ -385,67 +319,3 @@ int axp221_get_sid(unsigned int *sid)
return 0;
}
-
-int axp_gpio_direction_input(unsigned int pin)
-{
- switch (pin) {
- case SUNXI_GPIO_AXP0_VBUS_DETECT:
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-int axp_gpio_direction_output(unsigned int pin, unsigned int val)
-{
- int ret;
-
- switch (pin) {
- case SUNXI_GPIO_AXP0_VBUS_ENABLE:
- ret = axp221_clrbits(AXP221_MISC_CTRL,
- AXP221_MISC_CTRL_N_VBUSEN_FUNC);
- if (ret)
- return ret;
-
- return axp_gpio_set_value(pin, val);
- default:
- return -EINVAL;
- }
-}
-
-int axp_gpio_get_value(unsigned int pin)
-{
- int ret;
- u8 val;
-
- switch (pin) {
- case SUNXI_GPIO_AXP0_VBUS_DETECT:
- ret = pmic_bus_read(AXP221_POWER_STATUS, &val);
- if (ret)
- return ret;
-
- return !!(val & AXP221_POWER_STATUS_VBUS_AVAIL);
- default:
- return -EINVAL;
- }
-}
-
-int axp_gpio_set_value(unsigned int pin, unsigned int val)
-{
- int ret;
-
- switch (pin) {
- case SUNXI_GPIO_AXP0_VBUS_ENABLE:
- if (val)
- ret = axp221_setbits(AXP221_VBUS_IPSOUT,
- AXP221_VBUS_IPSOUT_DRIVEBUS);
- else
- ret = axp221_clrbits(AXP221_VBUS_IPSOUT,
- AXP221_VBUS_IPSOUT_DRIVEBUS);
-
- if (ret)
- return ret;
- }
-
- return 0;
-}
diff --git a/drivers/serial/arm_dcc.c b/drivers/serial/arm_dcc.c
index 5dfb02f..e777737 100644
--- a/drivers/serial/arm_dcc.c
+++ b/drivers/serial/arm_dcc.c
@@ -29,9 +29,9 @@
#include <common.h>
#include <serial.h>
-#if defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7)
/*
- * ARMV6
+ * ARMV6 & ARMV7
*/
#define DCC_RBIT (1 << 30)
#define DCC_WBIT (1 << 29)
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
index eda9f69..0edb643 100644
--- a/drivers/usb/host/ehci-sunxi.c
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2014 Roman Byshko
+ * Sunxi ehci glue
*
- * Roman Byshko <rbyshko@gmail.com>
+ * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (C) 2014 Roman Byshko <rbyshko@gmail.com>
*
* Based on code from
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
@@ -9,23 +10,32 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <asm/arch/usbc.h>
#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/usb_phy.h>
+#include <asm/io.h>
#include "ehci.h"
int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
struct ehci_hcor **hcor)
{
- int err;
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ int ahb_gate_offset;
- err = sunxi_usbc_request_resources(index + 1);
- if (err)
- return err;
+ ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 :
+ AHB_GATE_OFFSET_USB_EHCI0;
+ setbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset);
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ setbits_le32(&ccm->ahb_reset0_cfg, 1 << ahb_gate_offset);
+#endif
- sunxi_usbc_enable(index + 1);
- sunxi_usbc_vbus_enable(index + 1);
+ sunxi_usb_phy_init(index + 1);
+ sunxi_usb_phy_power_on(index + 1);
- *hccr = sunxi_usbc_get_io_base(index + 1);
+ if (index == 0)
+ *hccr = (void *)SUNXI_USB1_BASE;
+ else
+ *hccr = (void *)SUNXI_USB2_BASE;
*hcor = (struct ehci_hcor *)((uint32_t) *hccr
+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
@@ -39,8 +49,18 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
int ehci_hcd_stop(int index)
{
- sunxi_usbc_vbus_disable(index + 1);
- sunxi_usbc_disable(index + 1);
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ int ahb_gate_offset;
- return sunxi_usbc_free_resources(index + 1);
+ sunxi_usb_phy_power_off(index + 1);
+ sunxi_usb_phy_exit(index + 1);
+
+ ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 :
+ AHB_GATE_OFFSET_USB_EHCI0;
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ clrbits_le32(&ccm->ahb_reset0_cfg, 1 << ahb_gate_offset);
+#endif
+ clrbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset);
+
+ return 0;
}
diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h
index 27e4ed4..90288c4 100644
--- a/drivers/usb/musb-new/musb_regs.h
+++ b/drivers/usb/musb-new/musb_regs.h
@@ -458,8 +458,13 @@ static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
static inline u8 musb_read_configdata(void __iomem *mbase)
{
+#ifdef CONFIG_MACH_SUN8I_A33
+ /* <Sigh> allwinner saves a reg, and we need to hardcode this */
+ return 0xde;
+#else
musb_writeb(mbase, MUSB_INDEX, 0);
return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
+#endif
}
static inline u16 musb_read_hwvers(void __iomem *mbase)
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 7d90ebc..d1ee5f8 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -1,7 +1,7 @@
#include <common.h>
#include <watchdog.h>
#ifdef CONFIG_ARCH_SUNXI
-#include <asm/arch/usbc.h>
+#include <asm/arch/usb_phy.h>
#endif
#include <asm/errno.h>
#include <linux/usb/ch9.h>
@@ -195,12 +195,12 @@ int usb_reset_root_port(void)
* when clearing reset on low-speed devices, temporary disable
* squelch detection to work around this.
*/
- sunxi_usbc_enable_squelch_detect(0, 0);
+ sunxi_usb_phy_enable_squelch_detect(0, 0);
#endif
power = musb_readb(mbase, MUSB_POWER);
musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
#ifdef CONFIG_ARCH_SUNXI
- sunxi_usbc_enable_squelch_detect(0, 1);
+ sunxi_usb_phy_enable_squelch_detect(0, 1);
#endif
host->isr(0, host);
host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index c9a6a16..e8a3a23 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -22,8 +22,9 @@
*/
#include <common.h>
#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/usbc.h>
+#include <asm/arch/usb_phy.h>
#include <asm-generic/gpio.h>
#include "linux-compat.h"
#include "musb_core.h"
@@ -213,43 +214,57 @@ static void sunxi_musb_enable(struct musb *musb)
if (is_host_enabled(musb)) {
/* port power on */
- sunxi_usbc_vbus_enable(0);
+ sunxi_usb_phy_power_on(0);
}
}
static void sunxi_musb_disable(struct musb *musb)
{
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
pr_debug("%s():\n", __func__);
/* Put the controller back in a pristane state for "usb reset" */
if (musb->is_active) {
- sunxi_usbc_disable(0);
- sunxi_usbc_enable(0);
+ sunxi_usb_phy_exit(0);
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
+#endif
+ clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
+
+ mdelay(10);
+
+ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
+#endif
+ sunxi_usb_phy_init(0);
musb->is_active = 0;
}
}
static int sunxi_musb_init(struct musb *musb)
{
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int err;
pr_debug("%s():\n", __func__);
- err = sunxi_usbc_request_resources(0);
- if (err)
- return err;
-
if (is_host_enabled(musb)) {
- err = sunxi_usbc_vbus_detect(0);
+ err = sunxi_usb_phy_vbus_detect(0);
if (err) {
eprintf("Error: A charger is plugged into the OTG\n");
- sunxi_usbc_free_resources(0);
return -EIO;
}
}
musb->isr = sunxi_musb_interrupt;
- sunxi_usbc_enable(0);
+
+ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
+#endif
+ sunxi_usb_phy_init(0);
USBC_ConfigFIFO_Base();
USBC_EnableDpDmPullUp(musb->mregs);
@@ -273,10 +288,10 @@ static int sunxi_musb_exit(struct musb *musb)
USBC_DisableDpDmPullUp(musb->mregs);
USBC_DisableIdPullUp(musb->mregs);
- sunxi_usbc_vbus_disable(0);
- sunxi_usbc_disable(0);
+ sunxi_usb_phy_power_off(0);
+ sunxi_usb_phy_exit(0);
- return sunxi_usbc_free_resources(0);
+ return 0;
}
const struct musb_platform_ops sunxi_musb_ops = {
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index d2341b0..48dbdf5 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -84,7 +84,7 @@ static int sunxi_hdmi_hpd_detect(int hpd_delay)
CCM_HDMI_CTRL_PLL3);
/* Set ahb gating to pass */
-#ifdef CONFIG_MACH_SUN6I
+#ifdef CONFIG_SUNXI_GEN_SUN6I
setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
#endif
setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
@@ -113,7 +113,7 @@ static void sunxi_hdmi_shutdown(void)
clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE);
clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
-#ifdef CONFIG_MACH_SUN6I
+#ifdef CONFIG_SUNXI_GEN_SUN6I
clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
#endif
clock_set_pll3(0);
@@ -404,7 +404,7 @@ static void sunxi_composer_init(void)
sunxi_frontend_init();
-#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+#ifdef CONFIG_SUNXI_GEN_SUN6I
/* Reset off */
setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0);
#endif
@@ -549,7 +549,7 @@ static void sunxi_lcdc_init(void)
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
/* Reset off */
-#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+#ifdef CONFIG_SUNXI_GEN_SUN6I
setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
#else
setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST);
@@ -600,19 +600,19 @@ static void sunxi_lcdc_panel_enable(void)
* white while the lcd inits.
*/
pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
- if (pin != -1) {
+ if (pin >= 0) {
gpio_request(pin, "lcd_backlight_enable");
gpio_direction_output(pin, 0);
}
pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
- if (pin != -1) {
+ if (pin >= 0) {
gpio_request(pin, "lcd_backlight_pwm");
gpio_direction_output(pin, PWM_OFF);
}
reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET);
- if (reset_pin != -1) {
+ if (reset_pin >= 0) {
gpio_request(reset_pin, "lcd_reset");
gpio_direction_output(reset_pin, 0); /* Assert reset */
}
@@ -620,12 +620,12 @@ static void sunxi_lcdc_panel_enable(void)
/* Give the backlight some time to turn off and power up the panel. */
mdelay(40);
pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
- if (pin != -1) {
+ if (pin >= 0) {
gpio_request(pin, "lcd_power");
gpio_direction_output(pin, 1);
}
- if (reset_pin != -1)
+ if (reset_pin >= 0)
gpio_direction_output(reset_pin, 1); /* De-assert reset */
}
@@ -640,11 +640,11 @@ static void sunxi_lcdc_backlight_enable(void)
mdelay(40);
pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
- if (pin != -1)
+ if (pin >= 0)
gpio_direction_output(pin, 1);
pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
- if (pin != -1)
+ if (pin >= 0)
gpio_direction_output(pin, PWM_ON);
}
@@ -942,11 +942,14 @@ static void sunxi_vga_enable(void)
static void sunxi_drc_init(void)
{
-#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+#ifdef CONFIG_SUNXI_GEN_SUN6I
struct sunxi_ccm_reg * const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
/* On sun6i the drc must be clocked even when in pass-through mode */
+#ifdef CONFIG_MACH_SUN8I_A33
+ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT);
+#endif
setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0);
clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000);
#endif
@@ -958,7 +961,7 @@ static void sunxi_vga_external_dac_enable(void)
int pin;
pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN);
- if (pin != -1) {
+ if (pin >= 0) {
gpio_request(pin, "vga_enable");
gpio_direction_output(pin, 1);
}