- Add and enable watchdog driver
- Prepare for SYSRESET driven AXP poweroff
- Prepare for SoCs without MMC2
- Some fixes for extending SPL (SPL-DM for RISC-V)
- Some preparations for proper VBUS management
- Fix secure monitor move
This commit is contained in:
Tom Rini 2021-10-25 12:09:57 -04:00
commit 397b35f097
27 changed files with 305 additions and 35 deletions

View file

@ -1037,6 +1037,7 @@ config ARCH_SUNXI
select OF_CONTROL select OF_CONTROL
select OF_SEPARATE select OF_SEPARATE
select SPECIFY_CONSOLE_INDEX select SPECIFY_CONSOLE_INDEX
select SPL_SEPARATE_BSS if SPL
select SPL_STACK_R if SPL select SPL_STACK_R if SPL
select SPL_SYS_MALLOC_SIMPLE if SPL select SPL_SYS_MALLOC_SIMPLE if SPL
select SPL_SYS_THUMB_BUILD if !ARM64 select SPL_SYS_THUMB_BUILD if !ARM64
@ -1065,6 +1066,7 @@ config ARCH_SUNXI
imply SPL_POWER imply SPL_POWER
imply SPL_SERIAL imply SPL_SERIAL
imply USB_GADGET imply USB_GADGET
imply WDT
config ARCH_U8500 config ARCH_U8500
bool "ST-Ericsson U8500 Series" bool "ST-Ericsson U8500 Series"

View file

@ -122,7 +122,6 @@
reg = <0x030090a0 0x20>; reg = <0x030090a0 0x20>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc24M>; clocks = <&osc24M>;
status = "disabled";
}; };
pio: pinctrl@300b000 { pio: pinctrl@300b000 {

View file

@ -13,7 +13,9 @@
/ { / {
aliases { aliases {
mmc0 = &mmc0; mmc0 = &mmc0;
#if CONFIG_MMC_SUNXI_EXTRA_SLOT == 2
mmc1 = &mmc2; mmc1 = &mmc2;
#endif
}; };
binman: binman { binman: binman {

View file

@ -7,6 +7,7 @@
#include <image.h> #include <image.h>
#include <log.h> #include <log.h>
#include <spl.h> #include <spl.h>
#include <asm/arch/spl.h>
#include <asm/gpio.h> #include <asm/gpio.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/bitops.h> #include <linux/bitops.h>
@ -326,10 +327,13 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
int ret = 0; int ret = 0;
struct image_header *header; struct image_header *header;
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
int load_offset = readl(SPL_ADDR + 0x10);
load_offset = max(load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
spi0_init(); spi0_init();
spi0_read_data((void *)header, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40); spi0_read_data((void *)header, load_offset, 0x40);
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
image_get_magic(header) == FDT_MAGIC) { image_get_magic(header) == FDT_MAGIC) {
@ -342,14 +346,14 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
load.bl_len = 1; load.bl_len = 1;
load.read = spi_load_read; load.read = spi_load_read;
ret = spl_load_simple_fit(spl_image, &load, ret = spl_load_simple_fit(spl_image, &load,
CONFIG_SYS_SPI_U_BOOT_OFFS, header); load_offset, header);
} else { } else {
ret = spl_parse_image_header(spl_image, header); ret = spl_parse_image_header(spl_image, header);
if (ret) if (ret)
return ret; return ret;
spi0_read_data((void *)spl_image->load_addr, spi0_read_data((void *)spl_image->load_addr,
CONFIG_SYS_SPI_U_BOOT_OFFS, spl_image->size); load_offset, spl_image->size);
} }
spi0_deinit(); spi0_deinit();

View file

@ -2,6 +2,7 @@ config CLK_SUNXI
bool "Clock support for Allwinner SoCs" bool "Clock support for Allwinner SoCs"
depends on CLK && ARCH_SUNXI depends on CLK && ARCH_SUNXI
select DM_RESET select DM_RESET
select SPL_DM_RESET if SPL_CLK
default y default y
help help
This enables support for common clock driver API on Allwinner This enables support for common clock driver API on Allwinner

View file

@ -72,10 +72,12 @@ static int mmc_resource_init(int sdc_no)
priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
priv->mclkreg = &ccm->sd1_clk_cfg; priv->mclkreg = &ccm->sd1_clk_cfg;
break; break;
#ifdef SUNXI_MMC2_BASE
case 2: case 2:
priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
priv->mclkreg = &ccm->sd2_clk_cfg; priv->mclkreg = &ccm->sd2_clk_cfg;
break; break;
#endif
#ifdef SUNXI_MMC3_BASE #ifdef SUNXI_MMC3_BASE
case 3: case 3:
priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;

View file

@ -4,6 +4,7 @@
config PHY_SUN4I_USB config PHY_SUN4I_USB
bool "Allwinner Sun4I USB PHY driver" bool "Allwinner Sun4I USB PHY driver"
depends on ARCH_SUNXI depends on ARCH_SUNXI
select DM_REGULATOR
select PHY select PHY
help help
Enable this to support the transceiver that is part of Allwinner Enable this to support the transceiver that is part of Allwinner

View file

@ -26,6 +26,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <power/regulator.h>
#define REG_ISCR 0x00 #define REG_ISCR 0x00
#define REG_PHYCTL_A10 0x04 #define REG_PHYCTL_A10 0x04
@ -137,6 +138,7 @@ struct sun4i_usb_phy_data {
void __iomem *base; void __iomem *base;
const struct sun4i_usb_phy_cfg *cfg; const struct sun4i_usb_phy_cfg *cfg;
struct sun4i_usb_phy_plat *usb_phy; struct sun4i_usb_phy_plat *usb_phy;
struct udevice *vbus_power_supply;
}; };
static int initial_usb_scan_delay = CONFIG_INITIAL_USB_SCAN_DELAY; static int initial_usb_scan_delay = CONFIG_INITIAL_USB_SCAN_DELAY;
@ -391,22 +393,21 @@ int sun4i_usb_phy_vbus_detect(struct phy *phy)
{ {
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
int err, retries = 3; int err = 1, retries = 3;
debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det); if (usb_phy->gpio_vbus_det >= 0) {
if (usb_phy->gpio_vbus_det < 0)
return usb_phy->gpio_vbus_det;
err = gpio_get_value(usb_phy->gpio_vbus_det);
/*
* Vbus may have been provided by the board and just been turned of
* some milliseconds ago on reset, what we're measuring then is a
* residual charge on Vbus, sleep a bit and try again.
*/
while (err > 0 && retries--) {
mdelay(100);
err = gpio_get_value(usb_phy->gpio_vbus_det); err = gpio_get_value(usb_phy->gpio_vbus_det);
/*
* Vbus may have been provided by the board and just turned off
* some milliseconds ago on reset. What we're measuring then is
* a residual charge on Vbus. Sleep a bit and try again.
*/
while (err > 0 && retries--) {
mdelay(100);
err = gpio_get_value(usb_phy->gpio_vbus_det);
}
} else if (data->vbus_power_supply) {
err = regulator_get_enable(data->vbus_power_supply);
} }
return err; return err;
@ -417,8 +418,6 @@ int sun4i_usb_phy_id_detect(struct phy *phy)
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det);
if (usb_phy->gpio_id_det < 0) if (usb_phy->gpio_id_det < 0)
return usb_phy->gpio_id_det; return usb_phy->gpio_id_det;
@ -452,6 +451,9 @@ static int sun4i_usb_phy_probe(struct udevice *dev)
if (IS_ERR(data->base)) if (IS_ERR(data->base))
return PTR_ERR(data->base); return PTR_ERR(data->base);
device_get_supply_regulator(dev, "usb0_vbus_power-supply",
&data->vbus_power_supply);
data->usb_phy = plat; data->usb_phy = plat;
for (i = 0; i < data->cfg->num_phys; i++) { for (i = 0; i < data->cfg->num_phys; i++) {
struct sun4i_usb_phy_plat *phy = &plat[i]; struct sun4i_usb_phy_plat *phy = &plat[i];

View file

@ -79,6 +79,7 @@ int axp_init(void)
return 0; return 0;
} }
#if !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
pmic_bus_write(AXP152_SHUTDOWN, AXP152_POWEROFF); pmic_bus_write(AXP152_SHUTDOWN, AXP152_POWEROFF);
@ -89,3 +90,4 @@ int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
/* not reached */ /* not reached */
return 0; return 0;
} }
#endif

View file

@ -230,6 +230,7 @@ int axp_init(void)
return 0; return 0;
} }
#if !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
pmic_bus_write(AXP209_SHUTDOWN, AXP209_POWEROFF); pmic_bus_write(AXP209_SHUTDOWN, AXP209_POWEROFF);
@ -240,3 +241,4 @@ int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
/* not reached */ /* not reached */
return 0; return 0;
} }
#endif

View file

@ -264,6 +264,7 @@ int axp_get_sid(unsigned int *sid)
return 0; return 0;
} }
#if !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
pmic_bus_write(AXP221_SHUTDOWN, AXP221_SHUTDOWN_POWEROFF); pmic_bus_write(AXP221_SHUTDOWN, AXP221_SHUTDOWN_POWEROFF);
@ -274,3 +275,4 @@ int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
/* not reached */ /* not reached */
return 0; return 0;
} }
#endif

View file

@ -69,7 +69,7 @@ int axp_init(void)
return ret; return ret;
} }
#ifndef CONFIG_PSCI_RESET #if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
pmic_bus_write(AXP305_SHUTDOWN, AXP305_POWEROFF); pmic_bus_write(AXP305_SHUTDOWN, AXP305_POWEROFF);

View file

@ -219,6 +219,7 @@ int axp_init(void)
return pmic_bus_init(); return pmic_bus_init();
} }
#if !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
pmic_bus_write(AXP809_SHUTDOWN, AXP809_SHUTDOWN_POWEROFF); pmic_bus_write(AXP809_SHUTDOWN, AXP809_SHUTDOWN_POWEROFF);
@ -229,3 +230,4 @@ int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
/* not reached */ /* not reached */
return 0; return 0;
} }
#endif

View file

@ -255,6 +255,7 @@ int axp_init(void)
return 0; return 0;
} }
#if !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
pmic_bus_write(AXP818_SHUTDOWN, AXP818_SHUTDOWN_POWEROFF); pmic_bus_write(AXP818_SHUTDOWN, AXP818_SHUTDOWN_POWEROFF);
@ -265,3 +266,4 @@ int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
/* not reached */ /* not reached */
return 0; return 0;
} }
#endif

View file

@ -66,6 +66,8 @@ config PMIC_ACT8846
config PMIC_AXP config PMIC_AXP
bool "Enable Driver Model for X-Powers AXP PMICs" bool "Enable Driver Model for X-Powers AXP PMICs"
depends on DM_I2C depends on DM_I2C
select SYSRESET_CMD_POWEROFF if SYSRESET && CMD_POWEROFF
imply CMD_POWEROFF if SYSRESET
help help
This config enables driver-model PMIC uclass features for This config enables driver-model PMIC uclass features for
X-Powers AXP152, AXP2xx, and AXP8xx PMICs. X-Powers AXP152, AXP2xx, and AXP8xx PMICs.

View file

@ -1,8 +1,37 @@
// SPDX-License-Identifier: GPL-2.0+ // SPDX-License-Identifier: GPL-2.0+
#include <axp_pmic.h>
#include <dm.h> #include <dm.h>
#include <dm/lists.h>
#include <i2c.h> #include <i2c.h>
#include <power/pmic.h> #include <power/pmic.h>
#include <sysreset.h>
#if CONFIG_IS_ENABLED(SYSRESET)
static int axp_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
int ret;
if (type != SYSRESET_POWER_OFF)
return -EPROTONOSUPPORT;
ret = pmic_clrsetbits(dev->parent, AXP152_SHUTDOWN, 0, AXP152_POWEROFF);
if (ret < 0)
return ret;
return -EINPROGRESS;
}
static struct sysreset_ops axp_sysreset_ops = {
.request = axp_sysreset_request,
};
U_BOOT_DRIVER(axp_sysreset) = {
.name = "axp_sysreset",
.id = UCLASS_SYSRESET,
.ops = &axp_sysreset_ops,
};
#endif
static int axp_pmic_reg_count(struct udevice *dev) static int axp_pmic_reg_count(struct udevice *dev)
{ {
@ -16,6 +45,24 @@ static struct dm_pmic_ops axp_pmic_ops = {
.write = dm_i2c_write, .write = dm_i2c_write,
}; };
static int axp_pmic_bind(struct udevice *dev)
{
int ret;
ret = dm_scan_fdt_dev(dev);
if (ret)
return ret;
if (CONFIG_IS_ENABLED(SYSRESET)) {
ret = device_bind_driver_to_node(dev, "axp_sysreset", "axp_sysreset",
dev_ofnode(dev), NULL);
if (ret)
return ret;
}
return 0;
}
static const struct udevice_id axp_pmic_ids[] = { static const struct udevice_id axp_pmic_ids[] = {
{ .compatible = "x-powers,axp152" }, { .compatible = "x-powers,axp152" },
{ .compatible = "x-powers,axp202" }, { .compatible = "x-powers,axp202" },
@ -33,6 +80,6 @@ U_BOOT_DRIVER(axp_pmic) = {
.name = "axp_pmic", .name = "axp_pmic",
.id = UCLASS_PMIC, .id = UCLASS_PMIC,
.of_match = axp_pmic_ids, .of_match = axp_pmic_ids,
.bind = dm_scan_fdt_dev, .bind = axp_pmic_bind,
.ops = &axp_pmic_ops, .ops = &axp_pmic_ops,
}; };

View file

@ -27,6 +27,7 @@ config WATCHDOG_TIMEOUT_MSECS
default 128000 if ARCH_MX31 || ARCH_MX5 || ARCH_MX6 default 128000 if ARCH_MX31 || ARCH_MX5 || ARCH_MX6
default 128000 if ARCH_MX7 || ARCH_VF610 default 128000 if ARCH_MX7 || ARCH_VF610
default 30000 if ARCH_SOCFPGA default 30000 if ARCH_SOCFPGA
default 16000 if ARCH_SUNXI
default 60000 default 60000
help help
Watchdog timeout in msec Watchdog timeout in msec
@ -270,6 +271,13 @@ config WDT_STM32MP
Enable the STM32 watchdog (IWDG) driver. Enable support to Enable the STM32 watchdog (IWDG) driver. Enable support to
configure STM32's on-SoC watchdog. configure STM32's on-SoC watchdog.
config WDT_SUNXI
bool "Allwinner sunxi watchdog timer support"
depends on WDT && ARCH_SUNXI
default y
help
Enable support for the watchdog timer in Allwinner sunxi SoCs.
config XILINX_TB_WATCHDOG config XILINX_TB_WATCHDOG
bool "Xilinx Axi watchdog timer support" bool "Xilinx Axi watchdog timer support"
depends on WDT depends on WDT

View file

@ -36,5 +36,6 @@ obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
obj-$(CONFIG_WDT_SP805) += sp805_wdt.o obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o

View file

@ -0,0 +1,188 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Derived from linux/drivers/watchdog/sunxi_wdt.c:
* Copyright (C) 2013 Carlo Caione
* Copyright (C) 2012 Henrik Nordstrom
*/
#include <dm.h>
#include <wdt.h>
#include <asm/io.h>
#include <linux/delay.h>
#define MSEC_PER_SEC 1000
#define WDT_MAX_TIMEOUT 16
#define WDT_TIMEOUT_MASK 0xf
#define WDT_CTRL_RELOAD ((1 << 0) | (0x0a57 << 1))
#define WDT_MODE_EN BIT(0)
struct sunxi_wdt_reg {
u8 wdt_ctrl;
u8 wdt_cfg;
u8 wdt_mode;
u8 wdt_timeout_shift;
u8 wdt_reset_mask;
u8 wdt_reset_val;
u32 wdt_key_val;
};
struct sunxi_wdt_priv {
void __iomem *base;
const struct sunxi_wdt_reg *regs;
};
/* Map of timeout in seconds to register value */
static const u8 wdt_timeout_map[1 + WDT_MAX_TIMEOUT] = {
[0] = 0x0,
[1] = 0x1,
[2] = 0x2,
[3] = 0x3,
[4] = 0x4,
[5] = 0x5,
[6] = 0x6,
[7] = 0x7,
[8] = 0x7,
[9] = 0x8,
[10] = 0x8,
[11] = 0x9,
[12] = 0x9,
[13] = 0xa,
[14] = 0xa,
[15] = 0xb,
[16] = 0xb,
};
static int sunxi_wdt_reset(struct udevice *dev)
{
struct sunxi_wdt_priv *priv = dev_get_priv(dev);
const struct sunxi_wdt_reg *regs = priv->regs;
void __iomem *base = priv->base;
writel(WDT_CTRL_RELOAD, base + regs->wdt_ctrl);
return 0;
}
static int sunxi_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
struct sunxi_wdt_priv *priv = dev_get_priv(dev);
const struct sunxi_wdt_reg *regs = priv->regs;
void __iomem *base = priv->base;
u32 val;
timeout /= MSEC_PER_SEC;
if (timeout > WDT_MAX_TIMEOUT)
timeout = WDT_MAX_TIMEOUT;
/* Set system reset function */
val = readl(base + regs->wdt_cfg);
val &= ~regs->wdt_reset_mask;
val |= regs->wdt_reset_val;
val |= regs->wdt_key_val;
writel(val, base + regs->wdt_cfg);
/* Set timeout and enable watchdog */
val = readl(base + regs->wdt_mode);
val &= ~(WDT_TIMEOUT_MASK << regs->wdt_timeout_shift);
val |= wdt_timeout_map[timeout] << regs->wdt_timeout_shift;
val |= WDT_MODE_EN;
val |= regs->wdt_key_val;
writel(val, base + regs->wdt_mode);
return sunxi_wdt_reset(dev);
}
static int sunxi_wdt_stop(struct udevice *dev)
{
struct sunxi_wdt_priv *priv = dev_get_priv(dev);
const struct sunxi_wdt_reg *regs = priv->regs;
void __iomem *base = priv->base;
writel(regs->wdt_key_val, base + regs->wdt_mode);
return 0;
}
static int sunxi_wdt_expire_now(struct udevice *dev, ulong flags)
{
int ret;
ret = sunxi_wdt_start(dev, 0, flags);
if (ret)
return ret;
mdelay(500);
return 0;
}
static const struct wdt_ops sunxi_wdt_ops = {
.reset = sunxi_wdt_reset,
.start = sunxi_wdt_start,
.stop = sunxi_wdt_stop,
.expire_now = sunxi_wdt_expire_now,
};
static const struct sunxi_wdt_reg sun4i_wdt_reg = {
.wdt_ctrl = 0x00,
.wdt_cfg = 0x04,
.wdt_mode = 0x04,
.wdt_timeout_shift = 3,
.wdt_reset_mask = 0x2,
.wdt_reset_val = 0x2,
};
static const struct sunxi_wdt_reg sun6i_wdt_reg = {
.wdt_ctrl = 0x10,
.wdt_cfg = 0x14,
.wdt_mode = 0x18,
.wdt_timeout_shift = 4,
.wdt_reset_mask = 0x3,
.wdt_reset_val = 0x1,
};
static const struct sunxi_wdt_reg sun20i_wdt_reg = {
.wdt_ctrl = 0x10,
.wdt_cfg = 0x14,
.wdt_mode = 0x18,
.wdt_timeout_shift = 4,
.wdt_reset_mask = 0x03,
.wdt_reset_val = 0x01,
.wdt_key_val = 0x16aa0000,
};
static const struct udevice_id sunxi_wdt_ids[] = {
{ .compatible = "allwinner,sun4i-a10-wdt", .data = (ulong)&sun4i_wdt_reg },
{ .compatible = "allwinner,sun6i-a31-wdt", .data = (ulong)&sun6i_wdt_reg },
{ .compatible = "allwinner,sun20i-d1-wdt", .data = (ulong)&sun20i_wdt_reg },
{ /* sentinel */ }
};
static int sunxi_wdt_probe(struct udevice *dev)
{
struct sunxi_wdt_priv *priv = dev_get_priv(dev);
priv->base = dev_remap_addr(dev);
if (!priv->base)
return -EINVAL;
priv->regs = (void *)dev_get_driver_data(dev);
if (!priv->regs)
return -EINVAL;
sunxi_wdt_stop(dev);
return 0;
}
U_BOOT_DRIVER(sunxi_wdt) = {
.name = "sunxi_wdt",
.id = UCLASS_WDT,
.of_match = sunxi_wdt_ids,
.probe = sunxi_wdt_probe,
.priv_auto = sizeof(struct sunxi_wdt_priv),
.ops = &sunxi_wdt_ops,
};

View file

@ -15,6 +15,7 @@ enum axp152_reg {
#define AXP152_POWEROFF (1 << 7) #define AXP152_POWEROFF (1 << 7)
/* For axp_gpio.c */ /* For axp_gpio.c */
#ifdef CONFIG_AXP152_POWER
#define AXP_GPIO0_CTRL 0x90 #define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x91 #define AXP_GPIO1_CTRL 0x91
#define AXP_GPIO2_CTRL 0x92 #define AXP_GPIO2_CTRL 0x92
@ -24,3 +25,4 @@ enum axp152_reg {
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ #define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x97 #define AXP_GPIO_STATE 0x97
#define AXP_GPIO_STATE_OFFSET 0 #define AXP_GPIO_STATE_OFFSET 0
#endif

View file

@ -74,6 +74,7 @@ enum axp209_reg {
#define AXP209_POWEROFF BIT(7) #define AXP209_POWEROFF BIT(7)
/* For axp_gpio.c */ /* For axp_gpio.c */
#ifdef CONFIG_AXP209_POWER
#define AXP_POWER_STATUS 0x00 #define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_VBUS_PRESENT BIT(5) #define AXP_POWER_STATUS_VBUS_PRESENT BIT(5)
#define AXP_GPIO0_CTRL 0x90 #define AXP_GPIO0_CTRL 0x90
@ -84,3 +85,4 @@ enum axp209_reg {
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ #define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94 #define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 4 #define AXP_GPIO_STATE_OFFSET 4
#endif

View file

@ -50,6 +50,7 @@
#define AXP221_SID 0x20 #define AXP221_SID 0x20
/* For axp_gpio.c */ /* For axp_gpio.c */
#ifdef CONFIG_AXP221_POWER
#define AXP_POWER_STATUS 0x00 #define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) #define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5)
#define AXP_VBUS_IPSOUT 0x30 #define AXP_VBUS_IPSOUT 0x30
@ -63,3 +64,4 @@
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ #define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94 #define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0 #define AXP_GPIO_STATE_OFFSET 0
#endif

View file

@ -44,6 +44,7 @@
#define AXP809_SHUTDOWN_POWEROFF (1 << 7) #define AXP809_SHUTDOWN_POWEROFF (1 << 7)
/* For axp_gpio.c */ /* For axp_gpio.c */
#ifdef CONFIG_AXP809_POWER
#define AXP_POWER_STATUS 0x00 #define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) #define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5)
#define AXP_VBUS_IPSOUT 0x30 #define AXP_VBUS_IPSOUT 0x30
@ -57,3 +58,4 @@
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ #define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94 #define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0 #define AXP_GPIO_STATE_OFFSET 0
#endif

View file

@ -58,6 +58,7 @@
#define AXP818_SHUTDOWN_POWEROFF (1 << 7) #define AXP818_SHUTDOWN_POWEROFF (1 << 7)
/* For axp_gpio.c */ /* For axp_gpio.c */
#ifdef CONFIG_AXP818_POWER
#define AXP_POWER_STATUS 0x00 #define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) #define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5)
#define AXP_VBUS_IPSOUT 0x30 #define AXP_VBUS_IPSOUT 0x30
@ -71,3 +72,4 @@
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ #define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94 #define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0 #define AXP_GPIO_STATE_OFFSET 0
#endif

View file

@ -5,27 +5,16 @@
* X-Powers AX Power Management IC support header * X-Powers AX Power Management IC support header
*/ */
#ifndef _AXP_PMIC_H_ #ifndef _AXP_PMIC_H_
#define _AXP_PMIC_H_
#include <stdbool.h> #include <stdbool.h>
#ifdef CONFIG_AXP152_POWER
#include <axp152.h> #include <axp152.h>
#endif
#ifdef CONFIG_AXP209_POWER
#include <axp209.h> #include <axp209.h>
#endif
#ifdef CONFIG_AXP221_POWER
#include <axp221.h> #include <axp221.h>
#endif
#ifdef CONFIG_AXP305_POWER
#include <axp305.h> #include <axp305.h>
#endif
#ifdef CONFIG_AXP809_POWER
#include <axp809.h> #include <axp809.h>
#endif
#ifdef CONFIG_AXP818_POWER
#include <axp818.h> #include <axp818.h>
#endif
#define AXP_PMIC_MODE_REG 0x3e #define AXP_PMIC_MODE_REG 0x3e
#define AXP_PMIC_MODE_I2C 0x00 #define AXP_PMIC_MODE_I2C 0x00

View file

@ -12,6 +12,8 @@
* A23 specific configuration * A23 specific configuration
*/ */
#include <asm/arch/cpu.h>
#ifdef SUNXI_SRAM_A2_SIZE #ifdef SUNXI_SRAM_A2_SIZE
/* /*
* If the SoC has enough SRAM A2, use that for the secure monitor. * If the SoC has enough SRAM A2, use that for the secure monitor.

View file

@ -12,10 +12,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sunxi_image.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "imagetool.h" #include "imagetool.h"
#include "../arch/arm/include/asm/arch-sunxi/spl.h"
#define STAMP_VALUE 0x5F0A6C39 #define STAMP_VALUE 0x5F0A6C39