summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/clk_stm32mp1.c295
-rw-r--r--drivers/gpio/stm32_gpio.c149
-rw-r--r--drivers/net/dwc_eth_qos.c2
-rw-r--r--drivers/pinctrl/pinctrl-stmfx.c225
-rw-r--r--drivers/pinctrl/pinctrl_stm32.c27
-rw-r--r--drivers/power/regulator/stm32-vrefbuf.c16
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_tests.c98
7 files changed, 674 insertions, 138 deletions
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 6c5eddbd9a..c8840b9e5f 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -17,6 +17,7 @@
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/iopoll.h>
+#include <asm/arch/sys_proto.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/clock/stm32mp1-clksrc.h>
@@ -644,8 +645,18 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
};
#ifdef STM32MP1_CLOCK_TREE_INIT
+
/* define characteristic of PLL according type */
+#define DIVM_MIN 0
+#define DIVM_MAX 63
#define DIVN_MIN 24
+#define DIVP_MIN 0
+#define DIVP_MAX 127
+#define FRAC_MAX 8192
+
+#define PLL1600_VCO_MIN 800000000
+#define PLL1600_VCO_MAX 1600000000
+
static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
[PLL_800] = {
.refclk_min = 4,
@@ -1190,6 +1201,213 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk)
}
#ifdef STM32MP1_CLOCK_TREE_INIT
+
+bool stm32mp1_supports_opp(u32 opp_id, u32 cpu_type)
+{
+ unsigned int id;
+
+ switch (opp_id) {
+ case 1:
+ case 2:
+ id = opp_id;
+ break;
+ default:
+ id = 1; /* default value */
+ break;
+ }
+
+ switch (cpu_type) {
+ case CPU_STM32MP157Fxx:
+ case CPU_STM32MP157Dxx:
+ case CPU_STM32MP153Fxx:
+ case CPU_STM32MP153Dxx:
+ case CPU_STM32MP151Fxx:
+ case CPU_STM32MP151Dxx:
+ return true;
+ default:
+ return id == 1;
+ }
+}
+
+__weak void board_vddcore_init(u32 voltage_mv)
+{
+}
+
+/*
+ * gets OPP parameters (frequency in KHz and voltage in mV) from
+ * an OPP table subnode. Platform HW support capabilities are also checked.
+ * Returns 0 on success and a negative FDT error code on failure.
+ */
+static int stm32mp1_get_opp(u32 cpu_type, ofnode subnode,
+ u32 *freq_khz, u32 *voltage_mv)
+{
+ u32 opp_hw;
+ u64 read_freq_64;
+ u32 read_voltage_32;
+
+ *freq_khz = 0;
+ *voltage_mv = 0;
+
+ opp_hw = ofnode_read_u32_default(subnode, "opp-supported-hw", 0);
+ if (opp_hw)
+ if (!stm32mp1_supports_opp(opp_hw, cpu_type))
+ return -FDT_ERR_BADVALUE;
+
+ read_freq_64 = ofnode_read_u64_default(subnode, "opp-hz", 0) /
+ 1000ULL;
+ read_voltage_32 = ofnode_read_u32_default(subnode, "opp-microvolt", 0) /
+ 1000U;
+
+ if (!read_voltage_32 || !read_freq_64)
+ return -FDT_ERR_NOTFOUND;
+
+ /* Frequency value expressed in KHz must fit on 32 bits */
+ if (read_freq_64 > U32_MAX)
+ return -FDT_ERR_BADVALUE;
+
+ /* Millivolt value must fit on 16 bits */
+ if (read_voltage_32 > U16_MAX)
+ return -FDT_ERR_BADVALUE;
+
+ *freq_khz = (u32)read_freq_64;
+ *voltage_mv = read_voltage_32;
+
+ return 0;
+}
+
+/*
+ * parses OPP table in DT and finds the parameters for the
+ * highest frequency supported by the HW platform.
+ * Returns 0 on success and a negative FDT error code on failure.
+ */
+int stm32mp1_get_max_opp_freq(struct stm32mp1_clk_priv *priv, u64 *freq_hz)
+{
+ ofnode node, subnode;
+ int ret;
+ u32 freq = 0U, voltage = 0U;
+ u32 cpu_type = get_cpu_type();
+
+ node = ofnode_by_compatible(ofnode_null(), "operating-points-v2");
+ if (!ofnode_valid(node))
+ return -FDT_ERR_NOTFOUND;
+
+ ofnode_for_each_subnode(subnode, node) {
+ unsigned int read_freq;
+ unsigned int read_voltage;
+
+ ret = stm32mp1_get_opp(cpu_type, subnode,
+ &read_freq, &read_voltage);
+ if (ret)
+ continue;
+
+ if (read_freq > freq) {
+ freq = read_freq;
+ voltage = read_voltage;
+ }
+ }
+
+ if (!freq || !voltage)
+ return -FDT_ERR_NOTFOUND;
+
+ *freq_hz = (u64)1000U * freq;
+ board_vddcore_init(voltage);
+
+ return 0;
+}
+
+static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc,
+ u32 *pllcfg, u32 *fracv)
+{
+ u32 post_divm;
+ u32 input_freq;
+ u64 output_freq;
+ u64 freq;
+ u64 vco;
+ u32 divm, divn, divp, frac;
+ int i, ret;
+ u32 diff;
+ u32 best_diff = U32_MAX;
+
+ /* PLL1 is 1600 */
+ const u32 DIVN_MAX = stm32mp1_pll[PLL_1600].divn_max;
+ const u32 POST_DIVM_MIN = stm32mp1_pll[PLL_1600].refclk_min * 1000000U;
+ const u32 POST_DIVM_MAX = stm32mp1_pll[PLL_1600].refclk_max * 1000000U;
+
+ ret = stm32mp1_get_max_opp_freq(priv, &output_freq);
+ if (ret) {
+ debug("PLL1 OPP configuration not found (%d).\n", ret);
+ return ret;
+ }
+
+ switch (clksrc) {
+ case CLK_PLL12_HSI:
+ input_freq = stm32mp1_clk_get_fixed(priv, _HSI);
+ break;
+ case CLK_PLL12_HSE:
+ input_freq = stm32mp1_clk_get_fixed(priv, _HSE);
+ break;
+ default:
+ return -EINTR;
+ }
+
+ /* Following parameters have always the same value */
+ pllcfg[PLLCFG_Q] = 0;
+ pllcfg[PLLCFG_R] = 0;
+ pllcfg[PLLCFG_O] = PQR(1, 0, 0);
+
+ for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) {
+ post_divm = (u32)(input_freq / (divm + 1));
+ if (post_divm < POST_DIVM_MIN || post_divm > POST_DIVM_MAX)
+ continue;
+
+ for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+ freq = output_freq * (divm + 1) * (divp + 1);
+ divn = (u32)((freq / input_freq) - 1);
+ if (divn < DIVN_MIN || divn > DIVN_MAX)
+ continue;
+
+ frac = (u32)(((freq * FRAC_MAX) / input_freq) -
+ ((divn + 1) * FRAC_MAX));
+ /* 2 loops to refine the fractional part */
+ for (i = 2; i != 0; i--) {
+ if (frac > FRAC_MAX)
+ break;
+
+ vco = (post_divm * (divn + 1)) +
+ ((post_divm * (u64)frac) /
+ FRAC_MAX);
+ if (vco < (PLL1600_VCO_MIN / 2) ||
+ vco > (PLL1600_VCO_MAX / 2)) {
+ frac++;
+ continue;
+ }
+ freq = vco / (divp + 1);
+ if (output_freq < freq)
+ diff = (u32)(freq - output_freq);
+ else
+ diff = (u32)(output_freq - freq);
+ if (diff < best_diff) {
+ pllcfg[PLLCFG_M] = divm;
+ pllcfg[PLLCFG_N] = divn;
+ pllcfg[PLLCFG_P] = divp;
+ *fracv = frac;
+
+ if (diff == 0)
+ return 0;
+
+ best_diff = diff;
+ }
+ frac++;
+ }
+ }
+ }
+
+ if (best_diff == U32_MAX)
+ return -1;
+
+ return 0;
+}
+
static void stm32mp1_ls_osc_set(int enable, fdt_addr_t rcc, u32 offset,
u32 mask_on)
{
@@ -1661,9 +1879,12 @@ static int stm32mp1_clktree(struct udevice *dev)
unsigned int clksrc[CLKSRC_NB];
unsigned int clkdiv[CLKDIV_NB];
unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
- ofnode plloff[_PLL_NB];
- int ret, len;
- uint i;
+ unsigned int pllfracv[_PLL_NB];
+ unsigned int pllcsg[_PLL_NB][PLLCSG_NB];
+ bool pllcfg_valid[_PLL_NB];
+ bool pllcsg_set[_PLL_NB];
+ int ret;
+ int i, len;
int lse_css = 0;
const u32 *pkcs_cell;
@@ -1683,16 +1904,43 @@ static int stm32mp1_clktree(struct udevice *dev)
/* check mandatory field in each pll */
for (i = 0; i < _PLL_NB; i++) {
char name[12];
+ ofnode node;
sprintf(name, "st,pll@%d", i);
- plloff[i] = dev_read_subnode(dev, name);
- if (!ofnode_valid(plloff[i]))
- continue;
- ret = ofnode_read_u32_array(plloff[i], "cfg",
- pllcfg[i], PLLCFG_NB);
- if (ret < 0) {
- debug("field cfg invalid: error %d\n", ret);
- return -FDT_ERR_NOTFOUND;
+ node = dev_read_subnode(dev, name);
+ pllcfg_valid[i] = ofnode_valid(node);
+ pllcsg_set[i] = false;
+ if (pllcfg_valid[i]) {
+ debug("DT for PLL %d @ %s\n", i, name);
+ ret = ofnode_read_u32_array(node, "cfg",
+ pllcfg[i], PLLCFG_NB);
+ if (ret < 0) {
+ debug("field cfg invalid: error %d\n", ret);
+ return -FDT_ERR_NOTFOUND;
+ }
+ pllfracv[i] = ofnode_read_u32_default(node, "frac", 0);
+
+ ret = ofnode_read_u32_array(node, "csg", pllcsg[i],
+ PLLCSG_NB);
+ if (!ret) {
+ pllcsg_set[i] = true;
+ } else if (ret != -FDT_ERR_NOTFOUND) {
+ debug("invalid csg node for pll@%d res=%d\n",
+ i, ret);
+ return ret;
+ }
+ } else if (i == _PLL1) {
+ /* use OPP for PLL1 for A7 CPU */
+ debug("DT for PLL %d with OPP\n", i);
+ ret = stm32mp1_pll1_opp(priv,
+ clksrc[CLKSRC_PLL12],
+ pllcfg[i],
+ &pllfracv[i]);
+ if (ret) {
+ debug("PLL %d with OPP error = %d\n", i, ret);
+ return ret;
+ }
+ pllcfg_valid[i] = true;
}
}
@@ -1778,29 +2026,18 @@ static int stm32mp1_clktree(struct udevice *dev)
/* configure and start PLLs */
debug("configure PLLs\n");
for (i = 0; i < _PLL_NB; i++) {
- u32 fracv;
- u32 csg[PLLCSG_NB];
-
- debug("configure PLL %d @ %d\n", i,
- ofnode_to_offset(plloff[i]));
- if (!ofnode_valid(plloff[i]))
+ if (!pllcfg_valid[i])
continue;
-
- fracv = ofnode_read_u32_default(plloff[i], "frac", 0);
- pll_config(priv, i, pllcfg[i], fracv);
- ret = ofnode_read_u32_array(plloff[i], "csg", csg, PLLCSG_NB);
- if (!ret) {
- pll_csg(priv, i, csg);
- } else if (ret != -FDT_ERR_NOTFOUND) {
- debug("invalid csg node for pll@%d res=%d\n", i, ret);
- return ret;
- }
+ debug("configure PLL %d\n", i);
+ pll_config(priv, i, pllcfg[i], pllfracv[i]);
+ if (pllcsg_set[i])
+ pll_csg(priv, i, pllcsg[i]);
pll_start(priv, i);
}
/* wait and start PLLs ouptut when ready */
for (i = 0; i < _PLL_NB; i++) {
- if (!ofnode_valid(plloff[i]))
+ if (!pllcfg_valid[i])
continue;
debug("output PLL %d\n", i);
pll_output(priv, i, pllcfg[i][PLLCFG_O]);
@@ -2050,6 +2287,8 @@ static int stm32mp1_clk_probe(struct udevice *dev)
/* clock tree init is done only one time, before relocation */
if (!(gd->flags & GD_FLG_RELOC))
result = stm32mp1_clktree(dev);
+ if (result)
+ printf("clock tree initialization failed (%d)\n", result);
#endif
#ifndef CONFIG_SPL_BUILD
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index 4f710b6b6a..5bff27f75b 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -18,9 +18,65 @@
#include <linux/errno.h>
#include <linux/io.h>
-#define MODE_BITS(gpio_pin) (gpio_pin * 2)
+#define MODE_BITS(gpio_pin) ((gpio_pin) * 2)
#define MODE_BITS_MASK 3
-#define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16))
+#define BSRR_BIT(gpio_pin, value) BIT((gpio_pin) + (value ? 0 : 16))
+
+#define PUPD_BITS(gpio_pin) ((gpio_pin) * 2)
+#define PUPD_MASK 3
+
+#define OTYPE_BITS(gpio_pin) (gpio_pin)
+#define OTYPE_MSK 1
+
+static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs,
+ int idx,
+ int mode)
+{
+ int bits_index;
+ int mask;
+
+ bits_index = MODE_BITS(idx);
+ mask = MODE_BITS_MASK << bits_index;
+
+ clrsetbits_le32(&regs->moder, mask, mode << bits_index);
+}
+
+static int stm32_gpio_get_moder(struct stm32_gpio_regs *regs, int idx)
+{
+ return (readl(&regs->moder) >> MODE_BITS(idx)) & MODE_BITS_MASK;
+}
+
+static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs,
+ int idx,
+ enum stm32_gpio_otype otype)
+{
+ int bits;
+
+ bits = OTYPE_BITS(idx);
+ clrsetbits_le32(&regs->otyper, OTYPE_MSK << bits, otype << bits);
+}
+
+static enum stm32_gpio_otype stm32_gpio_get_otype(struct stm32_gpio_regs *regs,
+ int idx)
+{
+ return (readl(&regs->otyper) >> OTYPE_BITS(idx)) & OTYPE_MSK;
+}
+
+static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs,
+ int idx,
+ enum stm32_gpio_pupd pupd)
+{
+ int bits;
+
+ bits = PUPD_BITS(idx);
+ clrsetbits_le32(&regs->pupdr, PUPD_MASK << bits, pupd << bits);
+}
+
+static enum stm32_gpio_pupd stm32_gpio_get_pupd(struct stm32_gpio_regs *regs,
+ int idx)
+{
+ return (readl(&regs->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK;
+}
/*
* convert gpio offset to gpio index taking into account gpio holes
@@ -47,18 +103,13 @@ static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int bits_index;
- int mask;
int idx;
idx = stm32_offset_to_index(dev, offset);
if (idx < 0)
return idx;
- bits_index = MODE_BITS(idx);
- mask = MODE_BITS_MASK << bits_index;
-
- clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_IN << bits_index);
+ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
return 0;
}
@@ -68,18 +119,13 @@ static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset,
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int bits_index;
- int mask;
int idx;
idx = stm32_offset_to_index(dev, offset);
if (idx < 0)
return idx;
- bits_index = MODE_BITS(idx);
- mask = MODE_BITS_MASK << bits_index;
-
- clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
+ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
writel(BSRR_BIT(idx, value), &regs->bsrr);
@@ -141,12 +187,87 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset)
return GPIOF_FUNC;
}
+static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
+{
+ struct stm32_gpio_priv *priv = dev_get_priv(dev);
+ struct stm32_gpio_regs *regs = priv->regs;
+ int idx;
+
+ idx = stm32_offset_to_index(dev, offset);
+ if (idx < 0)
+ return idx;
+
+ if (flags & GPIOD_IS_OUT) {
+ int value = GPIOD_FLAGS_OUTPUT(flags);
+
+ if (flags & GPIOD_OPEN_DRAIN)
+ stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
+ else
+ stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
+ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
+ writel(BSRR_BIT(idx, value), &regs->bsrr);
+
+ } else if (flags & GPIOD_IS_IN) {
+ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
+ if (flags & GPIOD_PULL_UP)
+ stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP);
+ else if (flags & GPIOD_PULL_DOWN)
+ stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN);
+ }
+
+ return 0;
+}
+
+static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
+ ulong *flags)
+{
+ struct stm32_gpio_priv *priv = dev_get_priv(dev);
+ struct stm32_gpio_regs *regs = priv->regs;
+ int idx;
+ ulong dir_flags = 0;
+
+ idx = stm32_offset_to_index(dev, offset);
+ if (idx < 0)
+ return idx;
+
+ switch (stm32_gpio_get_moder(regs, idx)) {
+ case STM32_GPIO_MODE_OUT:
+ dir_flags |= GPIOD_IS_OUT;
+ if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD)
+ dir_flags |= GPIOD_OPEN_DRAIN;
+ if (readl(&regs->idr) & BIT(idx))
+ dir_flags |= GPIOD_IS_OUT_ACTIVE;
+ break;
+ case STM32_GPIO_MODE_IN:
+ dir_flags |= GPIOD_IS_IN;
+ switch (stm32_gpio_get_pupd(regs, idx)) {
+ case STM32_GPIO_PUPD_UP:
+ dir_flags |= GPIOD_PULL_UP;
+ break;
+ case STM32_GPIO_PUPD_DOWN:
+ dir_flags |= GPIOD_PULL_DOWN;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ *flags = dir_flags;
+
+ return 0;
+}
+
static const struct dm_gpio_ops gpio_stm32_ops = {
.direction_input = stm32_gpio_direction_input,
.direction_output = stm32_gpio_direction_output,
.get_value = stm32_gpio_get_value,
.set_value = stm32_gpio_set_value,
.get_function = stm32_gpio_get_function,
+ .set_dir_flags = stm32_gpio_set_dir_flags,
+ .get_dir_flags = stm32_gpio_get_dir_flags,
};
static int gpio_stm32_probe(struct udevice *dev)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 3f4437069b..62941bb175 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -2170,7 +2170,7 @@ static const struct udevice_id eqos_ids[] = {
.data = (ulong)&eqos_tegra186_config
},
{
- .compatible = "snps,dwmac-4.20a",
+ .compatible = "st,stm32mp1-dwmac",
.data = (ulong)&eqos_stm32_config
},
{
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
index a3240ccd5a..c2ea82770e 100644
--- a/drivers/pinctrl/pinctrl-stmfx.c
+++ b/drivers/pinctrl/pinctrl-stmfx.c
@@ -74,17 +74,61 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val)
return dm_i2c_reg_write(dev_get_parent(dev), offset, val);
}
-static int stmfx_gpio_get(struct udevice *dev, unsigned int offset)
+static int stmfx_read_reg(struct udevice *dev, u8 reg_base, uint offset)
{
- u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset);
+ u8 reg = reg_base + get_reg(offset);
u32 mask = get_mask(offset);
int ret;
ret = stmfx_read(dev, reg);
+ if (ret < 0)
+ return ret;
return ret < 0 ? ret : !!(ret & mask);
}
+static int stmfx_write_reg(struct udevice *dev, u8 reg_base, uint offset,
+ uint val)
+{
+ u8 reg = reg_base + get_reg(offset);
+ u32 mask = get_mask(offset);
+ int ret;
+
+ ret = stmfx_read(dev, reg);
+ if (ret < 0)
+ return ret;
+ ret = (ret & ~mask) | (val ? mask : 0);
+
+ return stmfx_write(dev, reg, ret);
+}
+
+static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int offset,
+ uint pupd)
+{
+ return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd);
+}
+
+static int stmfx_conf_get_pupd(struct udevice *dev, unsigned int offset)
+{
+ return stmfx_read_reg(dev, STMFX_REG_GPIO_PUPD, offset);
+}
+
+static int stmfx_conf_set_type(struct udevice *dev, unsigned int offset,
+ uint type)
+{
+ return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type);
+}
+
+static int stmfx_conf_get_type(struct udevice *dev, unsigned int offset)
+{
+ return stmfx_read_reg(dev, STMFX_REG_GPIO_TYPE, offset);
+}
+
+static int stmfx_gpio_get(struct udevice *dev, unsigned int offset)
+{
+ return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset);
+}
+
static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
{
u32 reg = value ? STMFX_REG_GPO_SET : STMFX_REG_GPO_CLR;
@@ -95,50 +139,103 @@ static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset)
{
- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
- u32 mask = get_mask(offset);
- int ret;
-
- ret = stmfx_read(dev, reg);
+ int ret = stmfx_read_reg(dev, STMFX_REG_GPIO_DIR, offset);
if (ret < 0)
return ret;
/* On stmfx, gpio pins direction is (0)input, (1)output. */
- return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT;
+ return ret ? GPIOF_OUTPUT : GPIOF_INPUT;
}
static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset)
{
- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
- u32 mask = get_mask(offset);
- int ret;
+ return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 0);
+}
- ret = stmfx_read(dev, reg);
+static int stmfx_gpio_direction_output(struct udevice *dev,
+ unsigned int offset, int value)
+{
+ int ret = stmfx_gpio_set(dev, offset, value);
if (ret < 0)
return ret;
- ret &= ~mask;
+ return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1);
+}
- return stmfx_write(dev, reg, ret & ~mask);
+static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
+{
+ int ret = -ENOTSUPP;
+
+ if (flags & GPIOD_IS_OUT) {
+ if (flags & GPIOD_OPEN_SOURCE)
+ return -ENOTSUPP;
+ if (flags & GPIOD_OPEN_DRAIN)
+ ret = stmfx_conf_set_type(dev, offset, 0);
+ else /* PUSH-PULL */
+ ret = stmfx_conf_set_type(dev, offset, 1);
+ if (ret)
+ return ret;
+ ret = stmfx_gpio_direction_output(dev, offset,
+ GPIOD_FLAGS_OUTPUT(flags));
+ } else if (flags & GPIOD_IS_IN) {
+ ret = stmfx_gpio_direction_input(dev, offset);
+ if (ret)
+ return ret;
+ if (flags & GPIOD_PULL_UP) {
+ ret = stmfx_conf_set_type(dev, offset, 1);
+ if (ret)
+ return ret;
+ ret = stmfx_conf_set_pupd(dev, offset, 1);
+ } else if (flags & GPIOD_PULL_DOWN) {
+ ret = stmfx_conf_set_type(dev, offset, 1);
+ if (ret)
+ return ret;
+ ret = stmfx_conf_set_pupd(dev, offset, 0);
+ }
+ }
+
+ return ret;
}
-static int stmfx_gpio_direction_output(struct udevice *dev,
- unsigned int offset, int value)
+static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
+ ulong *flags)
{
- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
- u32 mask = get_mask(offset);
+ ulong dir_flags = 0;
int ret;
- ret = stmfx_gpio_set(dev, offset, value);
- if (ret < 0)
- return ret;
-
- ret = stmfx_read(dev, reg);
- if (ret < 0)
- return ret;
+ if (stmfx_gpio_get_function(dev, offset) == GPIOF_OUTPUT) {
+ dir_flags |= GPIOD_IS_OUT;
+ ret = stmfx_conf_get_type(dev, offset);
+ if (ret < 0)
+ return ret;
+ if (ret == 0)
+ dir_flags |= GPIOD_OPEN_DRAIN;
+ /* 1 = push-pull (default), open source not supported */
+ ret = stmfx_gpio_get(dev, offset);
+ if (ret < 0)
+ return ret;
+ if (ret)
+ dir_flags |= GPIOD_IS_OUT_ACTIVE;
+ } else {
+ dir_flags |= GPIOD_IS_IN;
+ ret = stmfx_conf_get_type(dev, offset);
+ if (ret < 0)
+ return ret;
+ if (ret == 1) {
+ ret = stmfx_conf_get_pupd(dev, offset);
+ if (ret < 0)
+ return ret;
+ if (ret == 1)
+ dir_flags |= GPIOD_PULL_UP;
+ else
+ dir_flags |= GPIOD_PULL_DOWN;
+ }
+ }
+ *flags = dir_flags;
- return stmfx_write(dev, reg, ret | mask);
+ return 0;
}
static int stmfx_gpio_probe(struct udevice *dev)
@@ -169,6 +266,8 @@ static const struct dm_gpio_ops stmfx_gpio_ops = {
.get_function = stmfx_gpio_get_function,
.direction_input = stmfx_gpio_direction_input,
.direction_output = stmfx_gpio_direction_output,
+ .set_dir_flags = stmfx_gpio_set_dir_flags,
+ .get_dir_flags = stmfx_gpio_get_dir_flags,
};
U_BOOT_DRIVER(stmfx_gpio) = {
@@ -190,36 +289,6 @@ static const struct pinconf_param stmfx_pinctrl_conf_params[] = {
{ "output-low", PIN_CONFIG_OUTPUT, 0 },
};
-static int stmfx_pinctrl_set_pupd(struct udevice *dev,
- unsigned int pin, u32 pupd)
-{
- u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin);
- u32 mask = get_mask(pin);
- int ret;
-
- ret = stmfx_read(dev, reg);
- if (ret < 0)
- return ret;
- ret = (ret & ~mask) | (pupd ? mask : 0);
-
- return stmfx_write(dev, reg, ret);
-}
-
-static int stmfx_pinctrl_set_type(struct udevice *dev,
- unsigned int pin, u32 type)
-{
- u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin);
- u32 mask = get_mask(pin);
- int ret;
-
- ret = stmfx_read(dev, reg);
- if (ret < 0)
- return ret;
- ret = (ret & ~mask) | (type ? mask : 0);
-
- return stmfx_write(dev, reg, ret);
-}
-
static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin,
unsigned int param, unsigned int arg)
{
@@ -235,22 +304,22 @@ static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin,
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_DRIVE_PUSH_PULL:
- ret = stmfx_pinctrl_set_type(dev, pin, 0);
+ ret = stmfx_conf_set_type(dev, pin, 0);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- ret = stmfx_pinctrl_set_type(dev, pin, 1);
+ ret = stmfx_conf_set_type(dev, pin, 1);
if (ret)
return ret;
- ret = stmfx_pinctrl_set_pupd(dev, pin, 0);
+ ret = stmfx_conf_set_pupd(dev, pin, 0);
break;
case PIN_CONFIG_BIAS_PULL_UP:
- ret = stmfx_pinctrl_set_type(dev, pin, 1);
+ ret = stmfx_conf_set_type(dev, pin, 1);
if (ret)
return ret;
- ret = stmfx_pinctrl_set_pupd(dev, pin, 1);
+ ret = stmfx_conf_set_pupd(dev, pin, 1);
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- ret = stmfx_pinctrl_set_type(dev, pin, 1);
+ ret = stmfx_conf_set_type(dev, pin, 1);
break;
case PIN_CONFIG_OUTPUT:
ret = stmfx_gpio_direction_output(plat->gpio, pin, arg);
@@ -289,6 +358,34 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev,
return pin_name;
}
+static const char *stmfx_pinctrl_get_pin_conf(struct udevice *dev,
+ unsigned int pin, int func)
+{
+ int pupd, type;
+
+ type = stmfx_conf_get_type(dev, pin);
+ if (type < 0)
+ return "";
+
+ if (func == GPIOF_OUTPUT) {
+ if (type)
+ return "drive-open-drain";
+ else
+ return ""; /* default: push-pull*/
+ }
+ if (!type)
+ return ""; /* default: bias-disable*/
+
+ pupd = stmfx_conf_get_pupd(dev, pin);
+ if (pupd < 0)
+ return "";
+
+ if (pupd)
+ return "bias-pull-up";
+ else
+ return "bias-pull-down";
+}
+
static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev,
unsigned int selector,
char *buf, int size)
@@ -300,7 +397,9 @@ static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev,
if (func < 0)
return func;
- snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output");
+ snprintf(buf, size, "%s ", func == GPIOF_INPUT ? "input" : "output");
+
+ strncat(buf, stmfx_pinctrl_get_pin_conf(dev, selector, func), size);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index fc241fdcde..71fa29a389 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -45,6 +45,17 @@ static const char * const pinmux_mode[PINMUX_MODE_COUNT] = {
"alt function",
};
+static const char * const pinmux_output[] = {
+ [STM32_GPIO_PUPD_NO] = "bias-disable",
+ [STM32_GPIO_PUPD_UP] = "bias-pull-up",
+ [STM32_GPIO_PUPD_DOWN] = "bias-pull-down",
+};
+
+static const char * const pinmux_input[] = {
+ [STM32_GPIO_OTYPE_PP] = "drive-push-pull",
+ [STM32_GPIO_OTYPE_OD] = "drive-open-drain",
+};
+
static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
@@ -182,10 +193,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
int size)
{
struct udevice *gpio_dev;
+ struct stm32_gpio_priv *priv;
const char *label;
int mode;
int af_num;
unsigned int gpio_idx;
+ u32 pupd, otype;
/* look up for the bank which owns the requested pin */
gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
@@ -194,9 +207,9 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
return -ENODEV;
mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label);
-
dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n",
selector, gpio_idx, mode);
+ priv = dev_get_priv(gpio_dev);
switch (mode) {
@@ -211,9 +224,17 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num);
break;
case GPIOF_OUTPUT:
+ pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) &
+ PUPD_MASK;
+ snprintf(buf, size, "%s %s %s",
+ pinmux_mode[mode], pinmux_output[pupd],
+ label ? label : "");
+ break;
case GPIOF_INPUT:
- snprintf(buf, size, "%s %s",
- pinmux_mode[mode], label ? label : "");
+ otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK;
+ snprintf(buf, size, "%s %s %s",
+ pinmux_mode[mode], pinmux_input[otype],
+ label ? label : "");
break;
}
diff --git a/drivers/power/regulator/stm32-vrefbuf.c b/drivers/power/regulator/stm32-vrefbuf.c
index 250773514f..92136961c2 100644
--- a/drivers/power/regulator/stm32-vrefbuf.c
+++ b/drivers/power/regulator/stm32-vrefbuf.c
@@ -43,8 +43,20 @@ static int stm32_vrefbuf_set_enable(struct udevice *dev, bool enable)
u32 val;
int ret;
- clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ | STM32_ENVR,
- enable ? STM32_ENVR : STM32_HIZ);
+ if (enable && !(readl(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR)) {
+ /*
+ * There maybe an overshoot:
+ * - when disabling, then re-enabling vrefbuf too quickly
+ * - or upon platform reset as external capacitor maybe slow
+ * discharging (VREFBUF is HiZ at reset by default).
+ * So force active discharge (HiZ=0) for 1ms before enabling.
+ */
+ clrbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ);
+ udelay(1000);
+ }
+
+ clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_ENVR,
+ enable ? STM32_ENVR : 0);
if (!enable)
return 0;
diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c
index bacdd74705..952006aa14 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tests.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tests.c
@@ -14,10 +14,12 @@
#define ADDR_INVALID 0xFFFFFFFF
+#define PATTERN_DEFAULT "-"
+
DECLARE_GLOBAL_DATA_PTR;
static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
- size_t *bufsize, size_t default_size)
+ size_t *bufsize, size_t default_size, size_t min_size)
{
unsigned long value;
@@ -27,13 +29,14 @@ static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
arg_nb, argv[arg_nb]);
return -1;
}
- if (value > STM32_DDR_SIZE || value == 0) {
- sprintf(string, "invalid size %s", argv[arg_nb]);
+ if (value > STM32_DDR_SIZE || value < min_size) {
+ sprintf(string, "invalid size %s (min=%d)",
+ argv[arg_nb], min_size);
return -1;
}
- if (value & 0x3) {
- sprintf(string, "unaligned size %s",
- argv[arg_nb]);
+ if (value & (min_size - 1)) {
+ sprintf(string, "unaligned size %s (min=%d)",
+ argv[arg_nb], min_size);
return -1;
}
*bufsize = value;
@@ -102,6 +105,10 @@ static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
unsigned long value;
if (argc > arg_nb) {
+ if (!strcmp(argv[arg_nb], PATTERN_DEFAULT)) {
+ *pattern = default_pattern;
+ return 0;
+ }
if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
sprintf(string, "invalid %d parameter %s",
arg_nb, argv[arg_nb]);
@@ -441,7 +448,7 @@ static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
u32 bufsize;
u32 error;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, STM32_DDR_SIZE, 4))
return TEST_ERROR;
if (!is_power_of_2(bufsize)) {
sprintf(string, "size 0x%x is not a power of 2",
@@ -451,6 +458,7 @@ static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
if (get_addr(string, argc, argv, 1, &addr))
return TEST_ERROR;
+ printf("running at 0x%08x length 0x%x\n", addr, bufsize);
error = (u32)addressbus((u32 *)addr, bufsize);
if (error) {
sprintf(string, "0x%x: error for address 0x%x",
@@ -470,7 +478,7 @@ static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
size_t bufsize;
u32 error;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
return TEST_ERROR;
if (get_addr(string, argc, argv, 1, &addr))
return TEST_ERROR;
@@ -512,7 +520,7 @@ static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
u32 error = 0;
u32 data;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
return TEST_ERROR;
if (get_addr(string, argc, argv, 1, &addr))
return TEST_ERROR;
@@ -584,7 +592,7 @@ static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
u32 error = 0;
unsigned int seed;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -744,7 +752,7 @@ static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
int i;
enum test_result res = TEST_PASSED;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
return TEST_ERROR;
if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
return TEST_ERROR;
@@ -918,9 +926,11 @@ static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
enum test_result res = TEST_PASSED, pattern_res;
int i, bus_width;
const u32 **patterns;
- u32 bufsize;
+ u32 bufsize, addr;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 1, &addr))
return TEST_ERROR;
switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
@@ -934,15 +944,14 @@ static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
}
printf("running test pattern at 0x%08x length 0x%x width = %d\n",
- STM32_DDR_BASE, bufsize, bus_width);
+ addr, bufsize, bus_width);
patterns =
(const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
for (i = 0; i < NB_PATTERN; i++) {
printf("test data pattern %s:", patterns_comments[i]);
- pattern_res = test_loop(patterns[i], (u32 *)STM32_DDR_BASE,
- bufsize);
+ pattern_res = test_loop(patterns[i], (u32 *)addr, bufsize);
if (pattern_res != TEST_PASSED) {
printf("Failed\n");
return pattern_res;
@@ -1007,7 +1016,7 @@ static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -1042,7 +1051,7 @@ static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
u32 bufsize, nb_loop, loop = 0, addr, value;
int i;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -1076,7 +1085,7 @@ static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
u32 bufsize, nb_loop, loop = 0, addr, value;
int i;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -1114,7 +1123,7 @@ static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
u32 bufsize, nb_loop, loop = 0, addr, value;
int i;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -1156,7 +1165,7 @@ static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
int i, j;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -1203,7 +1212,7 @@ static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
u32 bitflip[4];
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
return TEST_ERROR;
if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
return TEST_ERROR;
@@ -1340,17 +1349,52 @@ static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
char *string, int argc, char *argv[])
{
enum test_result res = TEST_PASSED, result;
- int i, nb_error = 0;
+ int i, j, nb_error = 0, len;
u32 loop = 0, nb_loop;
+ int argc_test;
+ char *argv_test[4];
+ char loop_string[] = "1";
+ char pattern_string[] = PATTERN_DEFAULT;
+ u32 *addr;
if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, (u32 *)&addr))
+ return TEST_ERROR;
+
while (!nb_error) {
/* execute all the test except the lasts which are infinite */
for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
+ argc_test = 0;
+ j = 0;
+ len = strlen(test[i].usage);
+ if (argc > 1 && j < len &&
+ !strncmp("[size]", &test[i].usage[j], 6)) {
+ argv_test[argc_test++] = argv[1];
+ j += 7;
+ }
+ if (argc > 2) {
+ if (j < len &&
+ !strncmp("[loop]", &test[i].usage[j], 6)) {
+ argv_test[argc_test++] = loop_string;
+ j += 7;
+ }
+ if (j < len &&
+ !strncmp("[pattern]", &test[i].usage[j],
+ 9)) {
+ argv_test[argc_test++] = pattern_string;
+ j += 10;
+ }
+ if (j < len &&
+ !strncmp("[addr]", &test[i].usage[j], 6)) {
+ argv_test[argc_test++] = argv[2];
+ j += 7;
+ }
+ }
printf("execute %d:%s\n", (int)i, test[i].name);
- result = test[i].fct(ctl, phy, string, 0, NULL);
+ result = test[i].fct(ctl, phy, string,
+ argc_test, argv_test);
printf("result %d:%s = ", (int)i, test[i].name);
if (result != TEST_PASSED) {
nb_error++;
@@ -1381,7 +1425,7 @@ static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
****************************************************************/
const struct test_desc test[] = {
- {test_all, "All", "[loop]", "Execute all tests", 1 },
+ {test_all, "All", "[loop] [size] [addr]", "Execute all tests", 3 },
{test_databus, "Simple DataBus", "[addr]",
"Verifies each data line by walking 1 on fixed address",
1
@@ -1418,9 +1462,9 @@ const struct test_desc test[] = {
"Verifies r/w and memcopy(burst for pseudo random value.",
3
},
- {test_freq_pattern, "FrequencySelectivePattern", "[size]",
+ {test_freq_pattern, "FrequencySelectivePattern", "[size] [addr]",
"write & test patterns: Mostly Zero, Mostly One and F/n",
- 1
+ 2
},
{test_blockseq, "BlockSequential", "[size] [loop] [addr]",
"test incremental pattern",