diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/core/Kconfig | 30 | ||||
-rw-r--r-- | drivers/core/device.c | 20 | ||||
-rw-r--r-- | drivers/gpio/axp_gpio.c | 11 | ||||
-rw-r--r-- | drivers/mmc/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mmc/mv_sdhci.c | 41 | ||||
-rw-r--r-- | drivers/power/Kconfig | 208 | ||||
-rw-r--r-- | drivers/power/axp152.c | 40 | ||||
-rw-r--r-- | drivers/power/axp209.c | 117 | ||||
-rw-r--r-- | drivers/power/axp221.c | 41 | ||||
-rw-r--r-- | drivers/usb/gadget/f_fastboot.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-marvell.c | 86 | ||||
-rw-r--r-- | drivers/video/sunxi_display.c | 6 |
13 files changed, 439 insertions, 176 deletions
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/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/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/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, ¤t)) == 0 && + while ((rc = pmic_bus_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 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, ¤t)) == 0 && + while ((rc = pmic_bus_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 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, ®); + rc = pmic_bus_read(AXP209_LDO24_VOLTAGE, ®); 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, ®); + rc = pmic_bus_read(AXP209_LDO24_VOLTAGE, ®); 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/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); |