aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-10-12 12:01:00 -0400
committerTom Rini <trini@konsulko.com>2021-10-12 12:01:00 -0400
commit776bf6a5457eb0c61c367d1ee7e45733a1c72ed6 (patch)
tree032e8983decd749542208b52e935564aea0558a2 /drivers
parent618c77d99a23c72b16e31a7380b6f3b96e6dfa40 (diff)
parent39bd2c8e1aa9143c22f1fd20d054fc895a0880d2 (diff)
downloadu-boot-776bf6a5457eb0c61c367d1ee7e45733a1c72ed6.zip
u-boot-776bf6a5457eb0c61c367d1ee7e45733a1c72ed6.tar.gz
u-boot-776bf6a5457eb0c61c367d1ee7e45733a1c72ed6.tar.bz2
Merge tag 'u-boot-stm32-20211012' of https://source.denx.de/u-boot/custodians/u-boot-stm
- Disable ATAGS for STM32 MCU and MPU boards - Disable bi_boot_params for STM32 MCU and MPU boards - Update stm32-usbphyc node management - Convert CONFIG_STM32_FLASH to Kconfig for STM32 MCU boards - Convert some USB config flags to Kconfig for various boards - Convert CONFIG_BOOTCOMMAND flag to Kconfig for STM32 F429 board - Remove specific CONFIG_STV0991 flags - Remove unused CONFIG_USER_LOWLEVEL_INIT flag - Add ofdata_to_platdata() callback for stm32_spi driver - Update for stm32f7_i2c driver - Remove gpio_hog_probe_all() from STM32 MP1 board - Fix bind command Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/device.c2
-rw-r--r--drivers/core/lists.c4
-rw-r--r--drivers/core/root.c2
-rw-r--r--drivers/i2c/stm32f7_i2c.c91
-rw-r--r--drivers/misc/imx8/scu.c2
-rw-r--r--drivers/mtd/Kconfig7
-rw-r--r--drivers/phy/phy-stm32-usbphyc.c34
-rw-r--r--drivers/serial/serial-uclass.c2
-rw-r--r--drivers/spi/stm32_spi.c224
-rw-r--r--drivers/timer/timer-uclass.c2
-rw-r--r--drivers/usb/gadget/gadget_chips.h8
-rw-r--r--drivers/usb/host/usb-sandbox.c28
12 files changed, 253 insertions, 153 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 42ba2dc..d7a778a 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -1135,7 +1135,7 @@ int dev_enable_by_path(const char *path)
if (ret)
return ret;
- return lists_bind_fdt(parent, node, NULL, false);
+ return lists_bind_fdt(parent, node, NULL, NULL, false);
}
#endif
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 350b9d3..5d4f2ea 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -182,7 +182,7 @@ static int driver_check_compatible(const struct udevice_id *of_match,
}
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
- bool pre_reloc_only)
+ struct driver *drv, bool pre_reloc_only)
{
struct driver *driver = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver);
@@ -225,6 +225,8 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
for (entry = driver; entry != driver + n_ents; entry++) {
ret = driver_check_compatible(entry->of_match, &id,
compat);
+ if ((drv) && (drv == entry))
+ break;
if (!ret)
break;
}
diff --git a/drivers/core/root.c b/drivers/core/root.c
index fecdcb5..26b8195 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -276,7 +276,7 @@ static int dm_scan_fdt_node(struct udevice *parent, ofnode parent_node,
pr_debug(" - ignoring disabled device\n");
continue;
}
- err = lists_bind_fdt(parent, node, NULL, pre_reloc_only);
+ err = lists_bind_fdt(parent, node, NULL, NULL, pre_reloc_only);
if (err && !ret) {
ret = err;
debug("%s: ret=%d\n", node_name, ret);
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index 7b04a09..c6ae65b 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -45,6 +45,8 @@ struct stm32_i2c_regs {
/* STM32 I2C control 1 */
#define STM32_I2C_CR1_ANFOFF BIT(12)
+#define STM32_I2C_CR1_DNF_MASK GENMASK(11, 8)
+#define STM32_I2C_CR1_DNF(n) (((n) & 0xf) << 8)
#define STM32_I2C_CR1_ERRIE BIT(7)
#define STM32_I2C_CR1_TCIE BIT(6)
#define STM32_I2C_CR1_STOPIE BIT(5)
@@ -105,10 +107,8 @@ struct stm32_i2c_regs {
#define STM32_I2C_MAX_LEN 0xff
-#define STM32_I2C_DNF_DEFAULT 0
-#define STM32_I2C_DNF_MAX 16
+#define STM32_I2C_DNF_MAX 15
-#define STM32_I2C_ANALOG_FILTER_ENABLE 1
#define STM32_I2C_ANALOG_FILTER_DELAY_MIN 50 /* ns */
#define STM32_I2C_ANALOG_FILTER_DELAY_MAX 260 /* ns */
@@ -156,9 +156,8 @@ struct stm32_i2c_spec {
* @clock_src: I2C clock source frequency (Hz)
* @rise_time: Rise time (ns)
* @fall_time: Fall time (ns)
- * @dnf: Digital filter coefficient (0-16)
+ * @dnf: value of digital filter to apply
* @analog_filter: Analog filter delay (On/Off)
- * @fmp_clr_offset: Fast Mode Plus clear register offset from set register
*/
struct stm32_i2c_setup {
u32 speed_freq;
@@ -167,6 +166,13 @@ struct stm32_i2c_setup {
u32 fall_time;
u8 dnf;
bool analog_filter;
+};
+
+/**
+ * struct stm32_i2c_data - driver data for I2C configuration by compatible
+ * @fmp_clr_offset: Fast Mode Plus clear register offset from set register
+ */
+struct stm32_i2c_data {
u32 fmp_clr_offset;
};
@@ -197,16 +203,18 @@ struct stm32_i2c_timings {
* @regmap_sreg: register address for setting Fast Mode Plus bits
* @regmap_creg: register address for clearing Fast Mode Plus bits
* @regmap_mask: mask for Fast Mode Plus bits
+ * @dnf_dt: value of digital filter requested via dt
*/
struct stm32_i2c_priv {
struct stm32_i2c_regs *regs;
struct clk clk;
- struct stm32_i2c_setup *setup;
+ struct stm32_i2c_setup setup;
u32 speed;
struct regmap *regmap;
u32 regmap_sreg;
u32 regmap_creg;
u32 regmap_mask;
+ u32 dnf_dt;
};
static const struct stm32_i2c_spec i2c_specs[] = {
@@ -251,18 +259,11 @@ static const struct stm32_i2c_spec i2c_specs[] = {
},
};
-static const struct stm32_i2c_setup stm32f7_setup = {
- .rise_time = STM32_I2C_RISE_TIME_DEFAULT,
- .fall_time = STM32_I2C_FALL_TIME_DEFAULT,
- .dnf = STM32_I2C_DNF_DEFAULT,
- .analog_filter = STM32_I2C_ANALOG_FILTER_ENABLE,
+static const struct stm32_i2c_data stm32f7_data = {
+ .fmp_clr_offset = 0x00,
};
-static const struct stm32_i2c_setup stm32mp15_setup = {
- .rise_time = STM32_I2C_RISE_TIME_DEFAULT,
- .fall_time = STM32_I2C_FALL_TIME_DEFAULT,
- .dnf = STM32_I2C_DNF_DEFAULT,
- .analog_filter = STM32_I2C_ANALOG_FILTER_ENABLE,
+static const struct stm32_i2c_data stm32mp15_data = {
.fmp_clr_offset = 0x40,
};
@@ -506,14 +507,13 @@ static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
return 0;
}
-static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
+static int stm32_i2c_compute_solutions(u32 i2cclk,
+ struct stm32_i2c_setup *setup,
const struct stm32_i2c_spec *specs,
struct list_head *solutions)
{
struct stm32_i2c_timings *v;
u32 p_prev = STM32_PRESC_MAX;
- u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC,
- setup->clock_src);
u32 af_delay_min, af_delay_max;
u16 p, l, a;
int sdadel_min, sdadel_max, scldel_min;
@@ -581,7 +581,8 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
return ret;
}
-static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
+static int stm32_i2c_choose_solution(u32 i2cclk,
+ struct stm32_i2c_setup *setup,
const struct stm32_i2c_spec *specs,
struct list_head *solutions,
struct stm32_i2c_timings *s)
@@ -590,8 +591,6 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
u32 i2cbus = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC,
setup->speed_freq);
u32 clk_error_prev = i2cbus;
- u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC,
- setup->clock_src);
u32 clk_min, clk_max;
u32 af_delay_min;
u32 dnf_delay;
@@ -678,12 +677,13 @@ static const struct stm32_i2c_spec *get_specs(u32 rate)
}
static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
- struct stm32_i2c_setup *setup,
struct stm32_i2c_timings *output)
{
+ struct stm32_i2c_setup *setup = &i2c_priv->setup;
const struct stm32_i2c_spec *specs;
struct stm32_i2c_timings *v, *_v;
struct list_head solutions;
+ u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, setup->clock_src);
int ret;
specs = get_specs(setup->speed_freq);
@@ -701,6 +701,8 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
return -EINVAL;
}
+ /* Analog and Digital Filters */
+ setup->dnf = DIV_ROUND_CLOSEST(i2c_priv->dnf_dt, i2cclk);
if (setup->dnf > STM32_I2C_DNF_MAX) {
log_err("DNF out of bound %d/%d\n",
setup->dnf, STM32_I2C_DNF_MAX);
@@ -708,11 +710,11 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
}
INIT_LIST_HEAD(&solutions);
- ret = stm32_i2c_compute_solutions(setup, specs, &solutions);
+ ret = stm32_i2c_compute_solutions(i2cclk, setup, specs, &solutions);
if (ret)
goto exit;
- ret = stm32_i2c_choose_solution(setup, specs, &solutions, output);
+ ret = stm32_i2c_choose_solution(i2cclk, setup, specs, &solutions, output);
if (ret)
goto exit;
@@ -745,7 +747,7 @@ static u32 get_lower_rate(u32 rate)
static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
struct stm32_i2c_timings *timing)
{
- struct stm32_i2c_setup *setup = i2c_priv->setup;
+ struct stm32_i2c_setup *setup = &i2c_priv->setup;
int ret = 0;
setup->speed_freq = i2c_priv->speed;
@@ -757,7 +759,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
}
do {
- ret = stm32_i2c_compute_timing(i2c_priv, setup, timing);
+ ret = stm32_i2c_compute_timing(i2c_priv, timing);
if (ret) {
log_debug("failed to compute I2C timings.\n");
if (setup->speed_freq > I2C_SPEED_STANDARD_RATE) {
@@ -839,10 +841,15 @@ static int stm32_i2c_hw_config(struct stm32_i2c_priv *i2c_priv)
writel(timing, &regs->timingr);
/* Enable I2C */
- if (i2c_priv->setup->analog_filter)
+ if (i2c_priv->setup.analog_filter)
clrbits_le32(&regs->cr1, STM32_I2C_CR1_ANFOFF);
else
setbits_le32(&regs->cr1, STM32_I2C_CR1_ANFOFF);
+
+ /* Program the Digital Filter */
+ clrsetbits_le32(&regs->cr1, STM32_I2C_CR1_DNF_MASK,
+ STM32_I2C_CR1_DNF(i2c_priv->setup.dnf));
+
setbits_le32(&regs->cr1, STM32_I2C_CR1_PE);
return 0;
@@ -903,21 +910,26 @@ clk_free:
static int stm32_of_to_plat(struct udevice *dev)
{
+ const struct stm32_i2c_data *data;
struct stm32_i2c_priv *i2c_priv = dev_get_priv(dev);
u32 rise_time, fall_time;
int ret;
- i2c_priv->setup = (struct stm32_i2c_setup *)dev_get_driver_data(dev);
- if (!i2c_priv->setup)
+ data = (const struct stm32_i2c_data *)dev_get_driver_data(dev);
+ if (!data)
return -EINVAL;
- rise_time = dev_read_u32_default(dev, "i2c-scl-rising-time-ns", 0);
- if (rise_time)
- i2c_priv->setup->rise_time = rise_time;
+ rise_time = dev_read_u32_default(dev, "i2c-scl-rising-time-ns",
+ STM32_I2C_RISE_TIME_DEFAULT);
+
+ fall_time = dev_read_u32_default(dev, "i2c-scl-falling-time-ns",
+ STM32_I2C_FALL_TIME_DEFAULT);
+
+ i2c_priv->dnf_dt = dev_read_u32_default(dev, "i2c-digital-filter-width-ns", 0);
+ if (!dev_read_bool(dev, "i2c-digital-filter"))
+ i2c_priv->dnf_dt = 0;
- fall_time = dev_read_u32_default(dev, "i2c-scl-falling-time-ns", 0);
- if (fall_time)
- i2c_priv->setup->fall_time = fall_time;
+ i2c_priv->setup.analog_filter = dev_read_bool(dev, "i2c-analog-filter");
/* Optional */
i2c_priv->regmap = syscon_regmap_lookup_by_phandle(dev,
@@ -930,8 +942,7 @@ static int stm32_of_to_plat(struct udevice *dev)
return ret;
i2c_priv->regmap_sreg = fmp[1];
- i2c_priv->regmap_creg = fmp[1] +
- i2c_priv->setup->fmp_clr_offset;
+ i2c_priv->regmap_creg = fmp[1] + data->fmp_clr_offset;
i2c_priv->regmap_mask = fmp[2];
}
@@ -944,8 +955,8 @@ static const struct dm_i2c_ops stm32_i2c_ops = {
};
static const struct udevice_id stm32_i2c_of_match[] = {
- { .compatible = "st,stm32f7-i2c", .data = (ulong)&stm32f7_setup },
- { .compatible = "st,stm32mp15-i2c", .data = (ulong)&stm32mp15_setup },
+ { .compatible = "st,stm32f7-i2c", .data = (ulong)&stm32f7_data },
+ { .compatible = "st,stm32mp15-i2c", .data = (ulong)&stm32mp15_data },
{}
};
diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c
index 035a600..4ab5cb4 100644
--- a/drivers/misc/imx8/scu.c
+++ b/drivers/misc/imx8/scu.c
@@ -219,7 +219,7 @@ static int imx8_scu_bind(struct udevice *dev)
debug("%s(dev=%p)\n", __func__, dev);
ofnode_for_each_subnode(node, dev_ofnode(dev)) {
- ret = lists_bind_fdt(dev, node, &child, true);
+ ret = lists_bind_fdt(dev, node, &child, NULL, true);
if (ret)
return ret;
debug("bind child dev %s\n", child->name);
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 83c055a..a9c8c48 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -109,6 +109,13 @@ config HBMC_AM654
This is the driver for HyperBus controller on TI's AM65x and
other SoCs
+config STM32_FLASH
+ bool "STM32 MCU Flash driver"
+ depends on ARCH_STM32
+ help
+ This is the driver of embedded flash for some STMicroelectronics
+ STM32 MCU.
+
source "drivers/mtd/nand/Kconfig"
config SYS_NAND_MAX_CHIPS
diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
index 02d859a..9c1dcfa 100644
--- a/drivers/phy/phy-stm32-usbphyc.c
+++ b/drivers/phy/phy-stm32-usbphyc.c
@@ -339,8 +339,8 @@ static int stm32_usbphyc_probe(struct udevice *dev)
{
struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
struct reset_ctl reset;
- ofnode node;
- int i, ret;
+ ofnode node, connector;
+ int ret;
usbphyc->base = dev_read_addr(dev);
if (usbphyc->base == FDT_ADDR_T_NONE)
@@ -378,14 +378,18 @@ static int stm32_usbphyc_probe(struct udevice *dev)
return ret;
}
- /*
- * parse all PHY subnodes in order to populate regulator associated
- * to each PHY port
- */
- node = dev_read_first_subnode(dev);
- for (i = 0; i < MAX_PHYS; i++) {
- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i;
+ /* parse all PHY subnodes to populate regulator associated to each PHY port */
+ dev_for_each_subnode(node, dev) {
+ fdt_addr_t phy_id;
+ struct stm32_usbphyc_phy *usbphyc_phy;
+ phy_id = ofnode_read_u32_default(node, "reg", FDT_ADDR_T_NONE);
+ if (phy_id >= MAX_PHYS) {
+ dev_err(dev, "invalid reg value %lx for %s\n",
+ phy_id, ofnode_get_name(node));
+ return -ENOENT;
+ }
+ usbphyc_phy = usbphyc->phys + phy_id;
usbphyc_phy->init = false;
usbphyc_phy->powered = false;
ret = stm32_usbphyc_get_regulator(node, "phy-supply",
@@ -395,12 +399,12 @@ static int stm32_usbphyc_probe(struct udevice *dev)
return ret;
}
- ret = stm32_usbphyc_get_regulator(node, "vbus-supply",
- &usbphyc_phy->vbus);
- if (ret)
- usbphyc_phy->vbus = NULL;
-
- node = dev_read_next_subnode(node);
+ usbphyc_phy->vbus = NULL;
+ connector = ofnode_find_subnode(node, "connector");
+ if (ofnode_valid(connector)) {
+ ret = stm32_usbphyc_get_regulator(connector, "vbus-supply",
+ &usbphyc_phy->vbus);
+ }
}
/* Check if second port has to be used for host controller */
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 57a7848..30d4421 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -65,7 +65,7 @@ static int serial_check_stdout(const void *blob, struct udevice **devp)
* anyway.
*/
if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
- devp, false)) {
+ devp, NULL, false)) {
if (!device_probe(*devp))
return 0;
}
diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c
index bd85140..fe5419e 100644
--- a/drivers/spi/stm32_spi.c
+++ b/drivers/spi/stm32_spi.c
@@ -97,11 +97,14 @@
#define SPI_SIMPLEX_RX 2
#define SPI_HALF_DUPLEX 3
-struct stm32_spi_priv {
+struct stm32_spi_plat {
void __iomem *base;
struct clk clk;
struct reset_ctl rst_ctl;
struct gpio_desc cs_gpios[MAX_CS_COUNT];
+};
+
+struct stm32_spi_priv {
ulong bus_clk_rate;
unsigned int fifo_size;
unsigned int cur_bpw;
@@ -115,28 +118,32 @@ struct stm32_spi_priv {
bool cs_high;
};
-static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv)
+static void stm32_spi_write_txfifo(struct udevice *bus)
{
+ struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
+
while ((priv->tx_len > 0) &&
- (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP)) {
+ (readl(base + STM32_SPI_SR) & SPI_SR_TXP)) {
u32 offs = priv->cur_xferlen - priv->tx_len;
if (priv->tx_len >= sizeof(u32) &&
IS_ALIGNED((uintptr_t)(priv->tx_buf + offs), sizeof(u32))) {
const u32 *tx_buf32 = (const u32 *)(priv->tx_buf + offs);
- writel(*tx_buf32, priv->base + STM32_SPI_TXDR);
+ writel(*tx_buf32, base + STM32_SPI_TXDR);
priv->tx_len -= sizeof(u32);
} else if (priv->tx_len >= sizeof(u16) &&
IS_ALIGNED((uintptr_t)(priv->tx_buf + offs), sizeof(u16))) {
const u16 *tx_buf16 = (const u16 *)(priv->tx_buf + offs);
- writew(*tx_buf16, priv->base + STM32_SPI_TXDR);
+ writew(*tx_buf16, base + STM32_SPI_TXDR);
priv->tx_len -= sizeof(u16);
} else {
const u8 *tx_buf8 = (const u8 *)(priv->tx_buf + offs);
- writeb(*tx_buf8, priv->base + STM32_SPI_TXDR);
+ writeb(*tx_buf8, base + STM32_SPI_TXDR);
priv->tx_len -= sizeof(u8);
}
}
@@ -144,9 +151,12 @@ static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv)
log_debug("%d bytes left\n", priv->tx_len);
}
-static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv)
+static void stm32_spi_read_rxfifo(struct udevice *bus)
{
- u32 sr = readl(priv->base + STM32_SPI_SR);
+ struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
+ u32 sr = readl(base + STM32_SPI_SR);
u32 rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT;
while ((priv->rx_len > 0) &&
@@ -158,7 +168,7 @@ static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv)
(priv->rx_len >= sizeof(u32) || (sr & SPI_SR_RXWNE))) {
u32 *rx_buf32 = (u32 *)(priv->rx_buf + offs);
- *rx_buf32 = readl(priv->base + STM32_SPI_RXDR);
+ *rx_buf32 = readl(base + STM32_SPI_RXDR);
priv->rx_len -= sizeof(u32);
} else if (IS_ALIGNED((uintptr_t)(priv->rx_buf + offs), sizeof(u16)) &&
(priv->rx_len >= sizeof(u16) ||
@@ -166,38 +176,38 @@ static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv)
(rxplvl >= 2 || priv->cur_bpw > 8)))) {
u16 *rx_buf16 = (u16 *)(priv->rx_buf + offs);
- *rx_buf16 = readw(priv->base + STM32_SPI_RXDR);
+ *rx_buf16 = readw(base + STM32_SPI_RXDR);
priv->rx_len -= sizeof(u16);
} else {
u8 *rx_buf8 = (u8 *)(priv->rx_buf + offs);
- *rx_buf8 = readb(priv->base + STM32_SPI_RXDR);
+ *rx_buf8 = readb(base + STM32_SPI_RXDR);
priv->rx_len -= sizeof(u8);
}
- sr = readl(priv->base + STM32_SPI_SR);
+ sr = readl(base + STM32_SPI_SR);
rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT;
}
log_debug("%d bytes left\n", priv->rx_len);
}
-static int stm32_spi_enable(struct stm32_spi_priv *priv)
+static int stm32_spi_enable(void __iomem *base)
{
log_debug("\n");
/* Enable the SPI hardware */
- setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE);
+ setbits_le32(base + STM32_SPI_CR1, SPI_CR1_SPE);
return 0;
}
-static int stm32_spi_disable(struct stm32_spi_priv *priv)
+static int stm32_spi_disable(void __iomem *base)
{
log_debug("\n");
/* Disable the SPI hardware */
- clrbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE);
+ clrbits_le32(base + STM32_SPI_CR1, SPI_CR1_SPE);
return 0;
}
@@ -205,45 +215,48 @@ static int stm32_spi_disable(struct stm32_spi_priv *priv)
static int stm32_spi_claim_bus(struct udevice *slave)
{
struct udevice *bus = dev_get_parent(slave);
- struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
dev_dbg(slave, "\n");
/* Enable the SPI hardware */
- return stm32_spi_enable(priv);
+ return stm32_spi_enable(base);
}
static int stm32_spi_release_bus(struct udevice *slave)
{
struct udevice *bus = dev_get_parent(slave);
- struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
dev_dbg(slave, "\n");
/* Disable the SPI hardware */
- return stm32_spi_disable(priv);
+ return stm32_spi_disable(base);
}
static void stm32_spi_stopxfer(struct udevice *dev)
{
- struct stm32_spi_priv *priv = dev_get_priv(dev);
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
+ void __iomem *base = plat->base;
u32 cr1, sr;
int ret;
dev_dbg(dev, "\n");
- cr1 = readl(priv->base + STM32_SPI_CR1);
+ cr1 = readl(base + STM32_SPI_CR1);
if (!(cr1 & SPI_CR1_SPE))
return;
/* Wait on EOT or suspend the flow */
- ret = readl_poll_timeout(priv->base + STM32_SPI_SR, sr,
+ ret = readl_poll_timeout(base + STM32_SPI_SR, sr,
!(sr & SPI_SR_EOT), 100000);
if (ret < 0) {
if (cr1 & SPI_CR1_CSTART) {
- writel(cr1 | SPI_CR1_CSUSP, priv->base + STM32_SPI_CR1);
- if (readl_poll_timeout(priv->base + STM32_SPI_SR,
+ writel(cr1 | SPI_CR1_CSUSP, base + STM32_SPI_CR1);
+ if (readl_poll_timeout(base + STM32_SPI_SR,
sr, !(sr & SPI_SR_SUSP),
100000) < 0)
dev_err(dev, "Suspend request timeout\n");
@@ -251,11 +264,12 @@ static void stm32_spi_stopxfer(struct udevice *dev)
}
/* clear status flags */
- setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL);
+ setbits_le32(base + STM32_SPI_IFCR, SPI_IFCR_ALL);
}
static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable)
{
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
struct stm32_spi_priv *priv = dev_get_priv(dev);
dev_dbg(dev, "cs=%d enable=%d\n", cs, enable);
@@ -263,18 +277,20 @@ static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable)
if (cs >= MAX_CS_COUNT)
return -ENODEV;
- if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
+ if (!dm_gpio_is_valid(&plat->cs_gpios[cs]))
return -EINVAL;
if (priv->cs_high)
enable = !enable;
- return dm_gpio_set_value(&priv->cs_gpios[cs], enable ? 1 : 0);
+ return dm_gpio_set_value(&plat->cs_gpios[cs], enable ? 1 : 0);
}
static int stm32_spi_set_mode(struct udevice *bus, uint mode)
{
struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
u32 cfg2_clrb = 0, cfg2_setb = 0;
dev_dbg(bus, "mode=%d\n", mode);
@@ -295,7 +311,7 @@ static int stm32_spi_set_mode(struct udevice *bus, uint mode)
cfg2_clrb |= SPI_CFG2_LSBFRST;
if (cfg2_clrb || cfg2_setb)
- clrsetbits_le32(priv->base + STM32_SPI_CFG2,
+ clrsetbits_le32(base + STM32_SPI_CFG2,
cfg2_clrb, cfg2_setb);
if (mode & SPI_CS_HIGH)
@@ -308,6 +324,8 @@ static int stm32_spi_set_mode(struct udevice *bus, uint mode)
static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len)
{
struct stm32_spi_priv *priv = dev_get_priv(dev);
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
+ void __iomem *base = plat->base;
u32 fthlv, half_fifo;
/* data packet should not exceed 1/2 of fifo space */
@@ -321,7 +339,7 @@ static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len)
if (!fthlv)
fthlv = 1;
- clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_FTHLV,
+ clrsetbits_le32(base + STM32_SPI_CFG1, SPI_CFG1_FTHLV,
(fthlv - 1) << SPI_CFG1_FTHLV_SHIFT);
return 0;
@@ -330,6 +348,8 @@ static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len)
static int stm32_spi_set_speed(struct udevice *bus, uint hz)
{
struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
u32 mbrdiv;
long div;
@@ -353,7 +373,7 @@ static int stm32_spi_set_speed(struct udevice *bus, uint hz)
if (!mbrdiv)
return -EINVAL;
- clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_MBR,
+ clrsetbits_le32(base + STM32_SPI_CFG1, SPI_CFG1_MBR,
(mbrdiv - 1) << SPI_CFG1_MBR_SHIFT);
priv->cur_hz = hz;
@@ -367,6 +387,8 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
struct udevice *bus = dev_get_parent(slave);
struct dm_spi_slave_plat *slave_plat;
struct stm32_spi_priv *priv = dev_get_priv(bus);
+ struct stm32_spi_plat *plat = dev_get_plat(bus);
+ void __iomem *base = plat->base;
u32 sr;
u32 ifcr = 0;
u32 xferlen;
@@ -376,7 +398,7 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
xferlen = bitlen / 8;
if (xferlen <= SPI_CR2_TSIZE)
- writel(xferlen, priv->base + STM32_SPI_CR2);
+ writel(xferlen, base + STM32_SPI_CR2);
else
return -EMSGSIZE;
@@ -396,15 +418,15 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
priv->cur_xferlen = xferlen;
/* Disable the SPI hardware to unlock CFG1/CFG2 registers */
- stm32_spi_disable(priv);
+ stm32_spi_disable(base);
- clrsetbits_le32(priv->base + STM32_SPI_CFG2, SPI_CFG2_COMM,
+ clrsetbits_le32(base + STM32_SPI_CFG2, SPI_CFG2_COMM,
mode << SPI_CFG2_COMM_SHIFT);
stm32_spi_set_fthlv(bus, xferlen);
/* Enable the SPI hardware */
- stm32_spi_enable(priv);
+ stm32_spi_enable(base);
}
dev_dbg(bus, "priv->tx_len=%d priv->rx_len=%d\n",
@@ -416,12 +438,12 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
/* Be sure to have data in fifo before starting data transfer */
if (priv->tx_buf)
- stm32_spi_write_txfifo(priv);
+ stm32_spi_write_txfifo(bus);
- setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_CSTART);
+ setbits_le32(base + STM32_SPI_CR1, SPI_CR1_CSTART);
while (1) {
- sr = readl(priv->base + STM32_SPI_SR);
+ sr = readl(base + STM32_SPI_SR);
if (sr & SPI_SR_OVR) {
dev_err(bus, "Overrun: RX data lost\n");
@@ -433,7 +455,7 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
dev_warn(bus, "System too slow is limiting data throughput\n");
if (priv->rx_buf && priv->rx_len > 0)
- stm32_spi_read_rxfifo(priv);
+ stm32_spi_read_rxfifo(bus);
ifcr |= SPI_SR_SUSP;
}
@@ -443,23 +465,23 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
if (sr & SPI_SR_TXP)
if (priv->tx_buf && priv->tx_len > 0)
- stm32_spi_write_txfifo(priv);
+ stm32_spi_write_txfifo(bus);
if (sr & SPI_SR_RXP)
if (priv->rx_buf && priv->rx_len > 0)
- stm32_spi_read_rxfifo(priv);
+ stm32_spi_read_rxfifo(bus);
if (sr & SPI_SR_EOT) {
if (priv->rx_buf && priv->rx_len > 0)
- stm32_spi_read_rxfifo(priv);
+ stm32_spi_read_rxfifo(bus);
break;
}
- writel(ifcr, priv->base + STM32_SPI_IFCR);
+ writel(ifcr, base + STM32_SPI_IFCR);
}
/* clear status flags */
- setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL);
+ setbits_le32(base + STM32_SPI_IFCR, SPI_IFCR_ALL);
stm32_spi_stopxfer(bus);
if (flags & SPI_XFER_END)
@@ -470,42 +492,72 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
static int stm32_spi_get_fifo_size(struct udevice *dev)
{
- struct stm32_spi_priv *priv = dev_get_priv(dev);
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
+ void __iomem *base = plat->base;
u32 count = 0;
- stm32_spi_enable(priv);
+ stm32_spi_enable(base);
- while (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP)
- writeb(++count, priv->base + STM32_SPI_TXDR);
+ while (readl(base + STM32_SPI_SR) & SPI_SR_TXP)
+ writeb(++count, base + STM32_SPI_TXDR);
- stm32_spi_disable(priv);
+ stm32_spi_disable(base);
dev_dbg(dev, "%d x 8-bit fifo size\n", count);
return count;
}
+static int stm32_spi_of_to_plat(struct udevice *dev)
+{
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
+ int ret;
+
+ plat->base = dev_read_addr_ptr(dev);
+ if (!plat->base) {
+ dev_err(dev, "can't get registers base address\n");
+ return -ENOENT;
+ }
+
+ ret = clk_get_by_index(dev, 0, &plat->clk);
+ if (ret < 0)
+ return ret;
+
+ ret = reset_get_by_index(dev, 0, &plat->rst_ctl);
+ if (ret < 0)
+ goto clk_err;
+
+ ret = gpio_request_list_by_name(dev, "cs-gpios", plat->cs_gpios,
+ ARRAY_SIZE(plat->cs_gpios), 0);
+ if (ret < 0) {
+ dev_err(dev, "Can't get %s cs gpios: %d", dev->name, ret);
+ ret = -ENOENT;
+ goto clk_err;
+ }
+
+ return 0;
+
+clk_err:
+ clk_free(&plat->clk);
+
+ return ret;
+}
+
static int stm32_spi_probe(struct udevice *dev)
{
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
struct stm32_spi_priv *priv = dev_get_priv(dev);
+ void __iomem *base = plat->base;
unsigned long clk_rate;
int ret;
unsigned int i;
- priv->base = dev_remap_addr(dev);
- if (!priv->base)
- return -EINVAL;
-
/* enable clock */
- ret = clk_get_by_index(dev, 0, &priv->clk);
+ ret = clk_enable(&plat->clk);
if (ret < 0)
return ret;
- ret = clk_enable(&priv->clk);
- if (ret < 0)
- return ret;
-
- clk_rate = clk_get_rate(&priv->clk);
+ clk_rate = clk_get_rate(&plat->clk);
if (!clk_rate) {
ret = -EINVAL;
goto clk_err;
@@ -514,46 +566,34 @@ static int stm32_spi_probe(struct udevice *dev)
priv->bus_clk_rate = clk_rate;
/* perform reset */
- ret = reset_get_by_index(dev, 0, &priv->rst_ctl);
- if (ret < 0)
- goto clk_err;
-
- reset_assert(&priv->rst_ctl);
+ reset_assert(&plat->rst_ctl);
udelay(2);
- reset_deassert(&priv->rst_ctl);
-
- ret = gpio_request_list_by_name(dev, "cs-gpios", priv->cs_gpios,
- ARRAY_SIZE(priv->cs_gpios), 0);
- if (ret < 0) {
- dev_err(dev, "Can't get cs gpios: %d", ret);
- goto reset_err;
- }
+ reset_deassert(&plat->rst_ctl);
priv->fifo_size = stm32_spi_get_fifo_size(dev);
-
priv->cur_mode = SPI_FULL_DUPLEX;
priv->cur_xferlen = 0;
priv->cur_bpw = SPI_DEFAULT_WORDLEN;
- clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_DSIZE,
+ clrsetbits_le32(base + STM32_SPI_CFG1, SPI_CFG1_DSIZE,
priv->cur_bpw - 1);
- for (i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) {
- if (!dm_gpio_is_valid(&priv->cs_gpios[i]))
+ for (i = 0; i < ARRAY_SIZE(plat->cs_gpios); i++) {
+ if (!dm_gpio_is_valid(&plat->cs_gpios[i]))
continue;
- dm_gpio_set_dir_flags(&priv->cs_gpios[i],
+ dm_gpio_set_dir_flags(&plat->cs_gpios[i],
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
}
/* Ensure I2SMOD bit is kept cleared */
- clrbits_le32(priv->base + STM32_SPI_I2SCFGR, SPI_I2SCFGR_I2SMOD);
+ clrbits_le32(base + STM32_SPI_I2SCFGR, SPI_I2SCFGR_I2SMOD);
/*
* - SS input value high
* - transmitter half duplex direction
* - automatic communication suspend when RX-Fifo is full
*/
- setbits_le32(priv->base + STM32_SPI_CR1,
+ setbits_le32(base + STM32_SPI_CR1,
SPI_CR1_SSI | SPI_CR1_HDDIR | SPI_CR1_MASRX);
/*
@@ -562,40 +602,38 @@ static int stm32_spi_probe(struct udevice *dev)
* SS input value is determined by the SSI bit
* - keep control of all associated GPIOs
*/
- setbits_le32(priv->base + STM32_SPI_CFG2,
+ setbits_le32(base + STM32_SPI_CFG2,
SPI_CFG2_MASTER | SPI_CFG2_SSM | SPI_CFG2_AFCNTR);
return 0;
-reset_err:
- reset_free(&priv->rst_ctl);
-
clk_err:
- clk_disable(&priv->clk);
- clk_free(&priv->clk);
+ clk_disable(&plat->clk);
+ clk_free(&plat->clk);
return ret;
};
static int stm32_spi_remove(struct udevice *dev)
{
- struct stm32_spi_priv *priv = dev_get_priv(dev);
+ struct stm32_spi_plat *plat = dev_get_plat(dev);
+ void __iomem *base = plat->base;
int ret;
stm32_spi_stopxfer(dev);
- stm32_spi_disable(priv);
+ stm32_spi_disable(base);
- ret = reset_assert(&priv->rst_ctl);
+ ret = reset_assert(&plat->rst_ctl);
if (ret < 0)
return ret;
- reset_free(&priv->rst_ctl);
+ reset_free(&plat->rst_ctl);
- ret = clk_disable(&priv->clk);
+ ret = clk_disable(&plat->clk);
if (ret < 0)
return ret;
- clk_free(&priv->clk);
+ clk_free(&plat->clk);
return ret;
};
@@ -618,7 +656,9 @@ U_BOOT_DRIVER(stm32_spi) = {
.id = UCLASS_SPI,
.of_match = stm32_spi_ids,
.ops = &stm32_spi_ops,
- .priv_auto = sizeof(struct stm32_spi_priv),
+ .of_to_plat = stm32_spi_of_to_plat,
+ .plat_auto = sizeof(struct stm32_spi_plat),
+ .priv_auto = sizeof(struct stm32_spi_priv),
.probe = stm32_spi_probe,
.remove = stm32_spi_remove,
};
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 6ea9e39..cbc3647 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -148,7 +148,7 @@ int notrace dm_timer_init(void)
* If the timer is not marked to be bound before
* relocation, bind it anyway.
*/
- if (!lists_bind_fdt(dm_root(), node, &dev, false)) {
+ if (!lists_bind_fdt(dm_root(), node, &dev, NULL, false)) {
ret = device_probe(dev);
if (ret)
return ret;
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 0cdf47c..06e6a48 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -167,6 +167,12 @@
#define gadget_is_mtu3(g) 0
#endif
+#ifdef CONFIG_USB_GADGET_DWC2_OTG
+#define gadget_is_dwc2(g) (!strcmp("dwc2-udc", (g)->name))
+#else
+#define gadget_is_dwc2(g) 0
+#endif
+
/**
* usb_gadget_controller_number - support bcdDevice id convention
* @gadget: the controller being driven
@@ -232,5 +238,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x25;
else if (gadget_is_mtu3(gadget))
return 0x26;
+ else if (gadget_is_dwc2(gadget))
+ return 0x27;
return -ENOENT;
}
diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c
index d7cc92a..d1103dc 100644
--- a/drivers/usb/host/usb-sandbox.c
+++ b/drivers/usb/host/usb-sandbox.c
@@ -9,6 +9,13 @@
#include <log.h>
#include <usb.h>
#include <dm/root.h>
+#include <linux/usb/gadget.h>
+
+struct sandbox_udc {
+ struct usb_gadget gadget;
+};
+
+struct sandbox_udc *this_controller;
struct sandbox_usb_ctrl {
int rootdev;
@@ -117,6 +124,27 @@ static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev,
return ret;
}
+int usb_gadget_handle_interrupts(int index)
+{
+ return 0;
+}
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+ struct sandbox_udc *dev = this_controller;
+
+ return driver->bind(&dev->gadget);
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+ struct sandbox_udc *dev = this_controller;
+
+ driver->unbind(&dev->gadget);
+
+ return 0;
+}
+
static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev)
{
struct sandbox_usb_ctrl *ctrl = dev_get_priv(dev);