aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/adc/meson-saradc.c21
-rw-r--r--drivers/block/sandbox.c13
-rw-r--r--drivers/button/Kconfig8
-rw-r--r--drivers/button/Makefile1
-rw-r--r--drivers/button/button-adc.c146
-rw-r--r--drivers/clk/clk_stm32mp1.c62
-rw-r--r--drivers/clk/clk_versal.c11
-rw-r--r--drivers/clk/clk_zynq.c10
-rw-r--r--drivers/clk/clk_zynqmp.c49
-rw-r--r--drivers/core/Kconfig9
-rw-r--r--drivers/core/device.c36
-rw-r--r--drivers/ddr/altera/Kconfig6
-rw-r--r--drivers/ddr/altera/sequencer.c7
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_debug.c1
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_init.c8
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training.c14
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_db.c3
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_ip_def.h2
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c13
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_leveling.c3
-rw-r--r--drivers/ddr/marvell/a38x/ddr_ml_wrapper.h2
-rw-r--r--drivers/ddr/marvell/a38x/ddr_topology_def.h23
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_build_message.c2
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_plat.c18
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_plat.h2
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_spd.h8
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h22
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_topology.c14
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_topology.h2
-rw-r--r--drivers/ddr/marvell/a38x/xor.c8
-rw-r--r--drivers/ddr/marvell/axp/ddr3_dfs.c4
-rw-r--r--drivers/ddr/marvell/axp/ddr3_sdram.c2
-rw-r--r--drivers/ddr/marvell/axp/xor.c4
-rw-r--r--drivers/ddr/marvell/axp/xor.h4
-rw-r--r--drivers/fastboot/Kconfig9
-rw-r--r--drivers/fastboot/fb_command.c68
-rw-r--r--drivers/fastboot/fb_mmc.c210
-rw-r--r--drivers/firmware/scmi/mailbox_agent.c4
-rw-r--r--drivers/firmware/scmi/sandbox-scmi_agent.c2
-rw-r--r--drivers/firmware/scmi/sandbox-scmi_devices.c2
-rw-r--r--drivers/firmware/scmi/scmi_agent-uclass.c5
-rw-r--r--drivers/firmware/scmi/smccc_agent.c3
-rw-r--r--drivers/firmware/scmi/smt.c2
-rw-r--r--drivers/fpga/Kconfig2
-rw-r--r--drivers/fpga/zynqpl.c2
-rw-r--r--drivers/gpio/mpc8xxx_gpio.c7
-rw-r--r--drivers/i2c/i2c-cdns.c7
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c7
-rw-r--r--drivers/mmc/iproc_sdhci.c92
-rw-r--r--drivers/mmc/mtk-sd.c3
-rw-r--r--drivers/mmc/sandbox_mmc.c43
-rw-r--r--drivers/mmc/zynq_sdhci.c2
-rw-r--r--drivers/mtd/nand/core.c2
-rw-r--r--drivers/mtd/nand/raw/cortina_nand.c2
-rw-r--r--drivers/mtd/nand/spi/core.c3
-rw-r--r--drivers/mtd/nand/spi/gigadevice.c79
-rw-r--r--drivers/mtd/spi/spi-nor-core.c3
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c10
-rw-r--r--drivers/net/cortina_ni.c2
-rw-r--r--drivers/net/zynq_gem.c47
-rw-r--r--drivers/pci/fsl_pci_init.c5
-rw-r--r--drivers/pci/pci-aardvark.c18
-rw-r--r--drivers/pci/pci_mpc85xx.c25
-rw-r--r--drivers/pci/pci_mvebu.c76
-rw-r--r--drivers/power/pmic/Makefile2
-rw-r--r--drivers/power/pmic/pmic_max8997.c107
-rw-r--r--drivers/power/pmic/pmic_max8998.c32
-rw-r--r--drivers/rng/iproc_rng200.c28
-rw-r--r--drivers/serial/Kconfig7
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/ns16550.c4
-rw-r--r--drivers/serial/serial_zynq.c2
-rw-r--r--drivers/serial/usbtty.c16
-rw-r--r--drivers/spi/mxc_spi.c5
-rw-r--r--drivers/spi/nxp_fspi.c4
-rw-r--r--drivers/spi/stm32_qspi.c2
-rw-r--r--drivers/spi/zynq_qspi.c2
-rw-r--r--drivers/spi/zynq_spi.c2
-rw-r--r--drivers/spi/zynqmp_gqspi.c189
-rw-r--r--drivers/sysreset/Kconfig8
-rw-r--r--drivers/sysreset/sysreset-uclass.c2
-rw-r--r--drivers/thermal/imx_tmu.c6
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/gadget/dwc2_udc_otg.c8
-rw-r--r--drivers/usb/gadget/ep0.c16
-rw-r--r--drivers/usb/gadget/f_fastboot.c17
-rw-r--r--drivers/usb/mtu3/mtu3_qmu.c3
-rw-r--r--drivers/usb/musb/musb_core.c12
-rw-r--r--drivers/usb/musb/musb_udc.c61
-rw-r--r--drivers/video/dw_mipi_dsi.c9
-rw-r--r--drivers/video/stm32/stm32_dsi.c3
-rw-r--r--drivers/virtio/Kconfig1
-rw-r--r--drivers/virtio/virtio-uclass.c2
-rw-r--r--drivers/watchdog/xilinx_wwdt.c3
94 files changed, 1161 insertions, 675 deletions
diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 21db55831d..1a45a3a265 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/math64.h>
#include <linux/bitfield.h>
+#include <power/regulator.h>
#define MESON_SAR_ADC_REG0 0x00
#define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
@@ -656,7 +657,10 @@ static int meson_saradc_stop(struct udevice *dev)
static int meson_saradc_probe(struct udevice *dev)
{
+ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct meson_saradc_priv *priv = dev_get_priv(dev);
+ struct udevice *vref;
+ int vref_uv;
int ret;
ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
@@ -675,6 +679,23 @@ static int meson_saradc_probe(struct udevice *dev)
priv->active_channel = -1;
+ ret = device_get_supply_regulator(dev, "vref-supply", &vref);
+ if (ret) {
+ printf("can't get vref-supply: %d\n", ret);
+ return ret;
+ }
+
+ vref_uv = regulator_get_value(vref);
+ if (vref_uv < 0) {
+ printf("can't get vref-supply value: %d\n", vref_uv);
+ return vref_uv;
+ }
+
+ /* VDD supplied by common vref pin */
+ uc_pdata->vdd_supply = vref;
+ uc_pdata->vdd_microvolts = vref_uv;
+ uc_pdata->vss_microvolts = 0;
+
return 0;
}
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 9d7d68c007..e2f229b15d 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -231,6 +231,18 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
}
#ifdef CONFIG_BLK
+
+int sandbox_host_unbind(struct udevice *dev)
+{
+ struct host_block_dev *host_dev;
+
+ /* Data validity is checked in host_dev_bind() */
+ host_dev = dev_get_plat(dev);
+ os_close(host_dev->fd);
+
+ return 0;
+}
+
static const struct blk_ops sandbox_host_blk_ops = {
.read = host_block_read,
.write = host_block_write,
@@ -240,6 +252,7 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
.name = "sandbox_host_blk",
.id = UCLASS_BLK,
.ops = &sandbox_host_blk_ops,
+ .unbind = sandbox_host_unbind,
.plat_auto = sizeof(struct host_block_dev),
};
#else
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..6db3c5e93a 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
can provide access to board-specific buttons. Use of the device tree
for configuration is encouraged.
+config BUTTON_ADC
+ bool "Button adc"
+ depends on BUTTON
+ help
+ Enable support for buttons which are connected to Analog to Digital
+ Converter device. The ADC driver must use driver model. Buttons are
+ configured using the device tree.
+
config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
# Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com>
obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 0000000000..fd896c76f9
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ */
+
+#include <common.h>
+#include <adc.h>
+#include <button.h>
+#include <log.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/of_access.h>
+#include <dm/uclass-internal.h>
+
+/**
+ * struct button_adc_priv - private data for button-adc driver.
+ *
+ * @adc: Analog to Digital Converter device to which button is connected.
+ * @channel: channel of the ADC device to probe the button state.
+ * @min: minimal uV value to consider button as pressed.
+ * @max: maximal uV value to consider button as pressed.
+ */
+struct button_adc_priv {
+ struct udevice *adc;
+ int channel;
+ int min;
+ int max;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+ struct button_adc_priv *priv = dev_get_priv(dev);
+ unsigned int val;
+ int ret, uV;
+
+ ret = adc_start_channel(priv->adc, priv->channel);
+ if (ret)
+ return ret;
+
+ ret = adc_channel_data(priv->adc, priv->channel, &val);
+ if (ret)
+ return ret;
+
+ ret = adc_raw_to_uV(priv->adc, val, &uV);
+ if (ret)
+ return ret;
+
+ return (uV >= priv->min && uV < priv->max) ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_adc_of_to_plat(struct udevice *dev)
+{
+ struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+ struct button_adc_priv *priv = dev_get_priv(dev);
+ struct ofnode_phandle_args args;
+ u32 threshold, up_threshold, t;
+ ofnode node;
+ int ret;
+
+ /* Ignore the top-level button node */
+ if (!uc_plat->label)
+ return 0;
+
+ ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+ "#io-channel-cells", 0, 0, &args);
+ if (ret)
+ return ret;
+
+ ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, &priv->adc);
+ if (ret)
+ return ret;
+
+ ret = ofnode_read_u32(dev_ofnode(dev->parent),
+ "keyup-threshold-microvolt", &up_threshold);
+ if (ret)
+ return ret;
+
+ ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt",
+ &threshold);
+ if (ret)
+ return ret;
+
+ dev_for_each_subnode(node, dev->parent) {
+ ret = ofnode_read_u32(node, "press-threshold-microvolt", &t);
+ if (ret)
+ return ret;
+
+ if (t > threshold)
+ up_threshold = t;
+ }
+
+ priv->channel = args.args[0];
+ priv->min = threshold;
+ priv->max = up_threshold;
+
+ return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+ struct udevice *dev;
+ ofnode node;
+ int ret;
+
+ dev_for_each_subnode(node, parent) {
+ struct button_uc_plat *uc_plat;
+ const char *label;
+
+ label = ofnode_read_string(node, "label");
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+ return -EINVAL;
+ }
+ ret = device_bind_driver_to_node(parent, "button_adc",
+ ofnode_get_name(node),
+ node, &dev);
+ if (ret)
+ return ret;
+ uc_plat = dev_get_uclass_plat(dev);
+ uc_plat->label = label;
+ }
+
+ return 0;
+}
+
+static const struct button_ops button_adc_ops = {
+ .get_state = button_adc_get_state,
+};
+
+static const struct udevice_id button_adc_ids[] = {
+ { .compatible = "adc-keys" },
+ { }
+};
+
+U_BOOT_DRIVER(button_adc) = {
+ .name = "button_adc",
+ .id = UCLASS_BUTTON,
+ .of_match = button_adc_ids,
+ .ops = &button_adc_ops,
+ .priv_auto = sizeof(struct button_adc_priv),
+ .bind = button_adc_bind,
+ .of_to_plat = button_adc_of_to_plat,
+};
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 848e33f4e8..0c0ef366a1 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -250,7 +250,7 @@ DECLARE_GLOBAL_DATA_PTR;
enum stm32mp1_parent_id {
/*
* _HSI, _HSE, _CSI, _LSI, _LSE should not be moved
- * they are used as index in osc[] as entry point
+ * they are used as index in osc_clk[] as clock reference
*/
_HSI,
_HSE,
@@ -430,8 +430,7 @@ struct stm32mp1_clk_data {
struct stm32mp1_clk_priv {
fdt_addr_t base;
const struct stm32mp1_clk_data *data;
- ulong osc[NB_OSC];
- struct udevice *osc_dev[NB_OSC];
+ struct clk osc_clk[NB_OSC];
};
#define STM32MP1_CLK(off, b, idx, s) \
@@ -790,7 +789,7 @@ static ulong stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv, int idx)
return 0;
}
- return priv->osc[idx];
+ return clk_get_rate(&priv->osc_clk[idx]);
}
static int stm32mp1_clk_get_id(struct stm32mp1_clk_priv *priv, unsigned long id)
@@ -1545,7 +1544,7 @@ static int stm32mp1_hsidiv(fdt_addr_t rcc, ulong hsifreq)
break;
if (hsidiv == 4) {
- log_err("clk-hsi frequency invalid");
+ log_err("hsi frequency invalid");
return -1;
}
@@ -1952,13 +1951,13 @@ static int stm32mp1_clktree(struct udevice *dev)
* switch ON oscillator found in device-tree,
* HSI already ON after bootrom
*/
- if (priv->osc[_LSI])
+ if (clk_valid(&priv->osc_clk[_LSI]))
stm32mp1_lsi_set(rcc, 1);
- if (priv->osc[_LSE]) {
+ if (clk_valid(&priv->osc_clk[_LSE])) {
int bypass, digbyp;
u32 lsedrv;
- struct udevice *dev = priv->osc_dev[_LSE];
+ struct udevice *dev = priv->osc_clk[_LSE].dev;
bypass = dev_read_bool(dev, "st,bypass");
digbyp = dev_read_bool(dev, "st,digbypass");
@@ -1969,9 +1968,9 @@ static int stm32mp1_clktree(struct udevice *dev)
stm32mp1_lse_enable(rcc, bypass, digbyp, lsedrv);
}
- if (priv->osc[_HSE]) {
+ if (clk_valid(&priv->osc_clk[_HSE])) {
int bypass, digbyp, css;
- struct udevice *dev = priv->osc_dev[_HSE];
+ struct udevice *dev = priv->osc_clk[_HSE].dev;
bypass = dev_read_bool(dev, "st,bypass");
digbyp = dev_read_bool(dev, "st,digbypass");
@@ -1996,8 +1995,8 @@ static int stm32mp1_clktree(struct udevice *dev)
/* configure HSIDIV */
dev_dbg(dev, "configure HSIDIV\n");
- if (priv->osc[_HSI]) {
- stm32mp1_hsidiv(rcc, priv->osc[_HSI]);
+ if (clk_valid(&priv->osc_clk[_HSI])) {
+ stm32mp1_hsidiv(rcc, clk_get_rate(&priv->osc_clk[_HSI]));
stgen_config(priv);
}
@@ -2043,7 +2042,7 @@ static int stm32mp1_clktree(struct udevice *dev)
}
/* wait LSE ready before to use it */
- if (priv->osc[_LSE])
+ if (clk_valid(&priv->osc_clk[_LSE]))
stm32mp1_lse_wait(rcc);
/* configure with expected clock source */
@@ -2082,7 +2081,7 @@ static int stm32mp1_clktree(struct udevice *dev)
dev_dbg(dev, "oscillator off\n");
/* switch OFF HSI if not found in device-tree */
- if (!priv->osc[_HSI])
+ if (!clk_valid(&priv->osc_clk[_HSI]))
stm32mp1_hsi_set(rcc, 0);
/* Software Self-Refresh mode (SSR) during DDR initilialization */
@@ -2178,40 +2177,25 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate)
return -EINVAL;
}
-static void stm32mp1_osc_clk_init(const char *name,
- struct stm32mp1_clk_priv *priv,
- int index)
-{
- struct clk clk;
- struct udevice *dev = NULL;
-
- priv->osc[index] = 0;
- clk.id = 0;
- if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) {
- if (clk_request(dev, &clk))
- log_err("%s request", name);
- else
- priv->osc[index] = clk_get_rate(&clk);
- }
- priv->osc_dev[index] = dev;
-}
-
static void stm32mp1_osc_init(struct udevice *dev)
{
struct stm32mp1_clk_priv *priv = dev_get_priv(dev);
int i;
const char *name[NB_OSC] = {
- [_LSI] = "clk-lsi",
- [_LSE] = "clk-lse",
- [_HSI] = "clk-hsi",
- [_HSE] = "clk-hse",
- [_CSI] = "clk-csi",
+ [_LSI] = "lsi",
+ [_LSE] = "lse",
+ [_HSI] = "hsi",
+ [_HSE] = "hse",
+ [_CSI] = "csi",
[_I2S_CKIN] = "i2s_ckin",
};
for (i = 0; i < NB_OSC; i++) {
- stm32mp1_osc_clk_init(name[i], priv, i);
- dev_dbg(dev, "%d: %s => %x\n", i, name[i], (u32)priv->osc[i]);
+ if (clk_get_by_name(dev, name[i], &priv->osc_clk[i]))
+ dev_dbg(dev, "No source clock \"%s\"", name[i]);
+ else
+ dev_dbg(dev, "%s clock rate: %luHz\n",
+ name[i], clk_get_rate(&priv->osc_clk[i]));
}
}
diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c
index 908bc7519c..62523d2909 100644
--- a/drivers/clk/clk_versal.c
+++ b/drivers/clk/clk_versal.c
@@ -718,9 +718,20 @@ static ulong versal_clk_set_rate(struct clk *clk, ulong rate)
return clk_rate;
}
+static int versal_clk_enable(struct clk *clk)
+{
+ struct versal_clk_priv *priv = dev_get_priv(clk->dev);
+ u32 clk_id;
+
+ clk_id = priv->clk[clk->id].clk_id;
+
+ return xilinx_pm_request(PM_CLOCK_ENABLE, clk_id, 0, 0, 0, NULL);
+}
+
static struct clk_ops versal_clk_ops = {
.set_rate = versal_clk_set_rate,
.get_rate = versal_clk_get_rate,
+ .enable = versal_clk_enable,
};
static const struct udevice_id versal_clk_ids[] = {
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 3e3320900d..18915c3e04 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -445,11 +445,21 @@ static ulong zynq_clk_get_rate(struct clk *clk)
}
#endif
+static int dummy_enable(struct clk *clk)
+{
+ /*
+ * Add implementation but by default all clocks are enabled
+ * after power up which is only one supported case now.
+ */
+ return 0;
+}
+
static struct clk_ops zynq_clk_ops = {
.get_rate = zynq_clk_get_rate,
#ifndef CONFIG_SPL_BUILD
.set_rate = zynq_clk_set_rate,
#endif
+ .enable = dummy_enable,
};
static int zynq_clk_probe(struct udevice *dev)
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index e8acca0066..609d8e3b2f 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -199,6 +199,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
return CRF_APB_DDR_CTRL;
case qspi_ref:
return CRL_APB_QSPI_REF_CTRL;
+ case usb3_dual_ref:
+ return CRL_APB_USB3_DUAL_REF_CTRL;
case gem0_ref:
return CRL_APB_GEM0_REF_CTRL;
case gem1_ref:
@@ -207,6 +209,10 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
return CRL_APB_GEM2_REF_CTRL;
case gem3_ref:
return CRL_APB_GEM3_REF_CTRL;
+ case usb0_bus_ref:
+ return CRL_APB_USB0_BUS_REF_CTRL;
+ case usb1_bus_ref:
+ return CRL_APB_USB1_BUS_REF_CTRL;
case uart0_ref:
return CRL_APB_UART0_REF_CTRL;
case uart1_ref:
@@ -699,9 +705,52 @@ static int zynqmp_clk_probe(struct udevice *dev)
return 0;
}
+static int zynqmp_clk_enable(struct clk *clk)
+{
+ enum zynqmp_clk id = clk->id;
+ u32 reg, clk_ctrl, clkact_shift, mask;
+ int ret;
+
+ reg = zynqmp_clk_get_register(id);
+ debug("%s, clk_id:%x, clk_base:0x%x\n", __func__, id, reg);
+
+ switch (id) {
+ case usb0_bus_ref ... usb1:
+ clkact_shift = 25;
+ mask = 0x1;
+ break;
+ case gem0_ref ... gem3_ref:
+ clkact_shift = 25;
+ mask = 0x3;
+ break;
+ case qspi_ref ... can1_ref:
+ clkact_shift = 24;
+ mask = 0x1;
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ ret = zynqmp_mmio_read(reg, &clk_ctrl);
+ if (ret) {
+ printf("%s mio read fail\n", __func__);
+ return -EIO;
+ }
+
+ clk_ctrl |= (mask << clkact_shift);
+ ret = zynqmp_mmio_write(reg, mask << clkact_shift, clk_ctrl);
+ if (ret) {
+ printf("%s mio write fail\n", __func__);
+ return -EIO;
+ }
+
+ return ret;
+}
+
static struct clk_ops zynqmp_clk_ops = {
.set_rate = zynqmp_clk_set_rate,
.get_rate = zynqmp_clk_get_rate,
+ .enable = zynqmp_clk_enable,
};
static const struct udevice_id zynqmp_clk_ids[] = {
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 00554af499..1eccac28c6 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -329,15 +329,6 @@ config ACPIGEN
things like generating device-specific tables and returning the ACPI
name of a device.
-config INTEL_ACPIGEN
- bool "Support ACPI table generation for Intel SoCs"
- depends on ACPIGEN
- help
- This option adds some functions used for programatic generation of
- ACPI tables on Intel SoCs. This provides features for writing CPU
- information such as P states and T stages. Also included is a way
- to create a GNVS table and set it up.
-
config BOUNCE_BUFFER
bool "Include bounce buffer API"
help
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 625134921d..81f6880eac 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -92,15 +92,19 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
if (auto_seq && !(uc->uc_drv->flags & DM_UC_FLAG_NO_AUTO_SEQ))
dev->seq_ = uclass_find_next_free_seq(uc);
+ /* Check if we need to allocate plat */
if (drv->plat_auto) {
bool alloc = !plat;
+ /*
+ * For of-platdata, we try use the existing data, but if
+ * plat_auto is larger, we must allocate a new space
+ */
if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
- if (of_plat_size) {
+ if (of_plat_size)
dev_or_flags(dev, DM_FLAG_OF_PLATDATA);
- if (of_plat_size < drv->plat_auto)
- alloc = true;
- }
+ if (of_plat_size < drv->plat_auto)
+ alloc = true;
}
if (alloc) {
dev_or_flags(dev, DM_FLAG_ALLOC_PDATA);
@@ -109,6 +113,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
ret = -ENOMEM;
goto fail_alloc1;
}
+
+ /*
+ * For of-platdata, copy the old plat into the new
+ * space
+ */
if (CONFIG_IS_ENABLED(OF_PLATDATA) && plat)
memcpy(ptr, plat, of_plat_size);
dev_set_plat(dev, ptr);
@@ -128,9 +137,8 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
if (parent) {
size = parent->driver->per_child_plat_auto;
- if (!size) {
+ if (!size)
size = parent->uclass->uc_drv->per_child_plat_auto;
- }
if (size) {
dev_or_flags(dev, DM_FLAG_ALLOC_PARENT_PDATA);
ptr = calloc(1, size);
@@ -200,14 +208,18 @@ fail_uclass_bind:
}
}
fail_alloc3:
- if (dev_get_flags(dev) & DM_FLAG_ALLOC_UCLASS_PDATA) {
- free(dev_get_uclass_plat(dev));
- dev_set_uclass_plat(dev, NULL);
+ if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) {
+ if (dev_get_flags(dev) & DM_FLAG_ALLOC_UCLASS_PDATA) {
+ free(dev_get_uclass_plat(dev));
+ dev_set_uclass_plat(dev, NULL);
+ }
}
fail_alloc2:
- if (dev_get_flags(dev) & DM_FLAG_ALLOC_PDATA) {
- free(dev_get_plat(dev));
- dev_set_plat(dev, NULL);
+ if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) {
+ if (dev_get_flags(dev) & DM_FLAG_ALLOC_PDATA) {
+ free(dev_get_plat(dev));
+ dev_set_plat(dev, NULL);
+ }
}
fail_alloc1:
devres_release_all(dev);
diff --git a/drivers/ddr/altera/Kconfig b/drivers/ddr/altera/Kconfig
index 8f590dc5f6..4660d20def 100644
--- a/drivers/ddr/altera/Kconfig
+++ b/drivers/ddr/altera/Kconfig
@@ -1,8 +1,8 @@
config SPL_ALTERA_SDRAM
bool "SoCFPGA DDR SDRAM driver in SPL"
depends on SPL
- depends on TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 || TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX
- select RAM if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX
- select SPL_RAM if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX
+ depends on TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 || TARGET_SOCFPGA_SOC64
+ select RAM if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_SOC64
+ select SPL_RAM if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_SOC64
help
Enable DDR SDRAM controller for the SoCFPGA devices.
diff --git a/drivers/ddr/altera/sequencer.c b/drivers/ddr/altera/sequencer.c
index 2dbde49a9c..6b9b2e9094 100644
--- a/drivers/ddr/altera/sequencer.c
+++ b/drivers/ddr/altera/sequencer.c
@@ -3202,13 +3202,6 @@ rw_mgr_mem_calibrate_writes_center(struct socfpga_sdrseq *seq,
/* Centre DM */
debug_cond(DLEVEL >= 2, "%s:%d write_center: DM\n", __func__, __LINE__);
- /*
- * Set the left and right edge of each bit to an illegal value.
- * Use (seq->iocfg->io_out1_delay_max + 1) as an illegal value.
- */
- left_edge[0] = seq->iocfg->io_out1_delay_max + 1;
- right_edge[0] = seq->iocfg->io_out1_delay_max + 1;
-
/* Search for the/part of the window with DM shift. */
search_window(seq, 1, rank_bgn, write_group, &bgn_curr, &end_curr,
&bgn_best, &end_best, &win_best, 0);
diff --git a/drivers/ddr/marvell/a38x/ddr3_debug.c b/drivers/ddr/marvell/a38x/ddr3_debug.c
index 22e0cc4d91..f5fc964d6f 100644
--- a/drivers/ddr/marvell/a38x/ddr3_debug.c
+++ b/drivers/ddr/marvell/a38x/ddr3_debug.c
@@ -6,7 +6,6 @@
#include "ddr3_init.h"
#include "mv_ddr_training_db.h"
#include "mv_ddr_regs.h"
-#include <log.h>
u8 is_reg_dump = 0;
u8 debug_pbs = DEBUG_LEVEL_ERROR;
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c
index a971cc155a..f878b4512b 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.c
+++ b/drivers/ddr/marvell/a38x/ddr3_init.c
@@ -77,9 +77,6 @@ int ddr3_init(void)
return status;
}
-#if defined(CONFIG_PHY_STATIC_PRINT)
- mv_ddr_phy_static_print();
-#endif
/* Post MC/PHY initializations */
mv_ddr_post_training_soc_config(ddr_type);
@@ -104,6 +101,7 @@ int ddr3_init(void)
static int mv_ddr_training_params_set(u8 dev_num)
{
struct tune_train_params params;
+ struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
int status;
u32 cs_num;
int ck_delay;
@@ -136,6 +134,10 @@ static int mv_ddr_training_params_set(u8 dev_num)
if (ck_delay > 0)
params.ck_delay = ck_delay;
+ /* Use platform specific override ODT value */
+ if (tm->odt_config)
+ params.g_odt_config = tm->odt_config;
+
status = ddr3_tip_tune_training_params(dev_num, &params);
if (MV_OK != status) {
printf("%s Training Sequence - FAILED\n", ddr_type);
diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c
index 34cc170910..2512b58cb7 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training.c
@@ -7,8 +7,6 @@
#include "mv_ddr_common.h"
#include "mv_ddr_training_db.h"
#include "mv_ddr_regs.h"
-#include <log.h>
-#include <linux/delay.h>
#define GET_CS_FROM_MASK(mask) (cs_mask2_num[mask])
#define CS_CBE_VALUE(cs_num) (cs_cbe_reg[cs_num])
@@ -143,6 +141,7 @@ static struct reg_data odpg_default_value[] = {
{0x15a4, 0x0, MASK_ALL_BITS},
{0x15a8, 0x0, MASK_ALL_BITS},
{0x15ac, 0x0, MASK_ALL_BITS},
+ {0x1600, 0x0, MASK_ALL_BITS},
{0x1604, 0x0, MASK_ALL_BITS},
{0x1608, 0x0, MASK_ALL_BITS},
{0x160c, 0x0, MASK_ALL_BITS},
@@ -206,7 +205,6 @@ static int ddr3_tip_pad_inv(void)
if (tm->interface_params[0].as_bus_params[sphy].
is_ck_swap == 1 && sphy == 0) {
/* TODO: move this code to per platform one */
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
/* clock swap for both cs0 and cs1 */
data = (INVERT_PAD << INV_PAD2_OFFS |
INVERT_PAD << INV_PAD6_OFFS |
@@ -218,9 +216,6 @@ static int ddr3_tip_pad_inv(void)
DDR_PHY_CONTROL,
PHY_CTRL_PHY_REG,
data, data);
-#else /* !CONFIG_ARMADA_38X && !CONFIG_ARMADA_39X && !A70X0 && !A80X0 && !A3900 */
-#pragma message "unknown platform to configure ddr clock swap"
-#endif
}
}
@@ -1569,6 +1564,8 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
val = ((cl_mask_table[cl_value] & 0x1) << 2) |
((cl_mask_table[cl_value] & 0xe) << 3);
+ cs_mask[0] = 0xc;
+
CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MR_CMD0,
val, (0x7 << 4) | (0x1 << 2)));
@@ -2011,9 +2008,7 @@ int ddr3_tip_adll_regs_bypass(u32 dev_num, u32 reg_val1, u32 reg_val2)
static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
{
/* TODO: enable this functionality for other platforms */
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
struct init_cntr_param init_cntr_prm;
-#endif
int ret = MV_OK;
int adll_bypass_flag = 0;
u32 if_id;
@@ -2047,7 +2042,6 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
}
/* TODO: enable this functionality for other platforms */
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
if (is_adll_calib_before_init != 0) {
DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
("with adll calib before init\n"));
@@ -2078,7 +2072,6 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
return MV_FAIL;
}
}
-#endif
ret = adll_calibration(dev_num, ACCESS_TYPE_MULTICAST, 0, freq);
if (ret != MV_OK) {
@@ -2902,3 +2895,4 @@ unsigned int mv_ddr_misl_phy_odt_n_get(void)
return odt_n;
}
+
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c
index b2f11a8399..6aa7b6069e 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_db.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c
@@ -833,6 +833,9 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
pattern = pattern_table_get_isi_word16(index);
break;
default:
+ if (((int)type == 29) || ((int)type == 30))
+ break;
+
printf("error: %s: unsupported pattern type [%d] found\n",
__func__, (int)type);
pattern = 0;
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
index 2a68669f36..8765df7cfb 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
@@ -80,6 +80,8 @@
#define ADDR_SIZE_2GB 0x10000000
#define ADDR_SIZE_4GB 0x20000000
#define ADDR_SIZE_8GB 0x40000000
+#define ADDR_SIZE_16GB 0x80000000
+
enum hws_edge_compare {
EDGE_PF,
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
index 979f3530b7..102f9bd633 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
@@ -6,8 +6,6 @@
#include "ddr3_init.h"
#include "mv_ddr_regs.h"
#include "ddr_training_ip_db.h"
-#include <image.h>
-#include <linux/delay.h>
#define PATTERN_1 0x55555555
#define PATTERN_2 0xaaaaaaaa
@@ -614,9 +612,9 @@ int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
MASK_ALL_BITS));
}
- CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
- ODPG_DATA_BUFFER_OFFS_REG,
- load_addr, MASK_ALL_BITS));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ ODPG_DATA_BUFFER_OFFS_REG, load_addr, MASK_ALL_BITS));
return MV_OK;
}
@@ -864,8 +862,11 @@ int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
}
- for (pattern = 0; pattern < PATTERN_LAST; pattern++)
+ for (pattern = 0; pattern < PATTERN_LAST; pattern++) {
+ if (pattern == PATTERN_TEST)
+ continue;
ddr3_tip_load_pattern_to_mem(dev_num, pattern);
+ }
return MV_OK;
}
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c
index dadb06b318..6523281f2b 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c
@@ -7,7 +7,6 @@
#include "mv_ddr_training_db.h"
#include "ddr_training_ip_db.h"
#include "mv_ddr_regs.h"
-#include <linux/delay.h>
#define WL_ITERATION_NUM 10
@@ -916,10 +915,8 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num, int phase_remove)
DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("training done failed\n"));
} else { /* check for training pass */
reg_data = data_read[0];
-#if defined(CONFIG_ARMADA_38X) /* JIRA #1498 for 16 bit with ECC */
if (tm->bus_act_mask == 0xb) /* set to data to 0 to skip the check */
reg_data = 0;
-#endif
if (reg_data != PASS)
DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("training result failed\n"));
diff --git a/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h b/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
index ac9250f74e..7357311965 100644
--- a/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
+++ b/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
@@ -13,9 +13,7 @@
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
#define INTER_REGS_BASE SOC_REGS_PHY_BASE
-#endif
/*
* MV_DEBUG_INIT need to be defines, otherwise the output of the
diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h
index 34196b1662..7f2317edfa 100644
--- a/drivers/ddr/marvell/a38x/ddr_topology_def.h
+++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h
@@ -14,6 +14,11 @@
#define MV_DDR_MAX_BUS_NUM 9
#define MV_DDR_MAX_IFACE_NUM 1
+enum mv_ddr_twin_die {
+ NOT_COMBINED,
+ COMBINED,
+};
+
struct bus_params {
/* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */
u8 cs_bitmask;
@@ -113,6 +118,9 @@ struct mv_ddr_topology_map {
/* source of ddr configuration data */
enum mv_ddr_cfg_src cfg_src;
+ /* ddr twin-die */
+ enum mv_ddr_twin_die twin_die_combined;
+
/* raw spd data */
union mv_ddr_spd_data spd_data;
@@ -125,6 +133,9 @@ struct mv_ddr_topology_map {
/* electrical parameters */
unsigned int electrical_data[MV_DDR_EDATA_LAST];
+ /* ODT configuration */
+ u32 odt_config;
+
/* Clock enable mask */
u32 clk_enable;
@@ -148,7 +159,13 @@ enum mv_ddr_validation {
MV_DDR_VAL_DIS,
MV_DDR_VAL_RX,
MV_DDR_VAL_TX,
- MV_DDR_VAL_RX_TX
+ MV_DDR_VAL_RX_TX,
+ MV_DDR_MEMORY_CHECK
+};
+
+enum mv_ddr_sscg {
+ SSCG_EN,
+ SSCG_DIS,
};
struct mv_ddr_iface {
@@ -179,8 +196,12 @@ struct mv_ddr_iface {
/* ddr interface validation mode */
enum mv_ddr_validation validation;
+ /* ddr interface validation mode */
+ enum mv_ddr_sscg sscg;
+
/* ddr interface topology map */
struct mv_ddr_topology_map tm;
+
};
struct mv_ddr_iface *mv_ddr_iface_get(void);
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c
index cc6234fd40..a2bb8a96a6 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c
+++ b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c
@@ -1,3 +1,3 @@
// SPDX-License-Identifier: GPL-2.0
const char mv_ddr_build_message[] = "";
-const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-18.09.2";
+const char mv_ddr_version_string[] = "mv_ddr: 14.0.0";
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
index 72f0dfbbbb..faafc86ea2 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
@@ -4,10 +4,10 @@
*/
#include "ddr3_init.h"
+#include "mv_ddr_common.h"
#include "mv_ddr_training_db.h"
#include "mv_ddr_regs.h"
#include "mv_ddr_sys_env_lib.h"
-#include <linux/delay.h>
#define DDR_INTERFACES_NUM 1
#define DDR_INTERFACE_OCTETS_NUM 5
@@ -559,11 +559,7 @@ static int ddr3_tip_a38x_get_medium_freq(int dev_num, enum mv_ddr_freq *freq)
static int ddr3_tip_a38x_get_device_info(u8 dev_num, struct ddr3_device_info *info_ptr)
{
-#if defined(CONFIG_ARMADA_39X)
- info_ptr->device_id = 0x6900;
-#else
info_ptr->device_id = 0x6800;
-#endif
info_ptr->ck_delay = ck_delay;
return MV_OK;
@@ -666,11 +662,7 @@ static int mv_ddr_sw_db_init(u32 dev_num, u32 board_id)
ddr3_tip_dev_attr_set(dev_num, MV_ATTR_TIP_REV, MV_TIP_REV_4);
ddr3_tip_dev_attr_set(dev_num, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_POSITIVE);
ddr3_tip_dev_attr_set(dev_num, MV_ATTR_OCTET_PER_INTERFACE, DDR_INTERFACE_OCTETS_NUM);
-#ifdef CONFIG_ARMADA_39X
- ddr3_tip_dev_attr_set(dev_num, MV_ATTR_INTERLEAVE_WA, 1);
-#else
ddr3_tip_dev_attr_set(dev_num, MV_ATTR_INTERLEAVE_WA, 0);
-#endif
ca_delay = 0;
delay_enable = 1;
@@ -1016,7 +1008,7 @@ int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size)
return MV_BAD_VALUE;
}
- *cs_size = cs_mem_size << 20; /* write cs size in bytes */
+ *cs_size = cs_mem_size;
return MV_OK;
}
@@ -1025,9 +1017,11 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
{
u32 reg, cs;
uint64_t mem_total_size = 0;
+ uint64_t cs_mem_size_mb = 0;
uint64_t cs_mem_size = 0;
uint64_t mem_total_size_c, cs_mem_size_c;
+
#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
u32 physical_mem_size;
u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
@@ -1038,8 +1032,9 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
for (cs = 0; cs < MAX_CS_NUM; cs++) {
if (cs_ena & (1 << cs)) {
/* get CS size */
- if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK)
+ if (ddr3_calc_mem_cs_size(cs, &cs_mem_size_mb) != MV_OK)
return MV_FAIL;
+ cs_mem_size = cs_mem_size_mb * _1M;
#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
/*
@@ -1088,6 +1083,7 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
*/
mem_total_size_c = (mem_total_size >> 16) & 0xffffffffffff;
cs_mem_size_c = (cs_mem_size >> 16) & 0xffffffffffff;
+
/* if the sum less than 2 G - calculate the value */
if (mem_total_size_c + cs_mem_size_c < 0x10000)
mem_total_size += cs_mem_size;
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.h b/drivers/ddr/marvell/a38x/mv_ddr_plat.h
index 281d4c2301..44998847c2 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_plat.h
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.h
@@ -6,6 +6,8 @@
#ifndef _MV_DDR_PLAT_H
#define _MV_DDR_PLAT_H
+#include <linux/delay.h>
+
#define MAX_DEVICE_NUM 1
#define MAX_INTERFACE_NUM 1
#define MAX_BUS_NUM 5
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_spd.h b/drivers/ddr/marvell/a38x/mv_ddr_spd.h
index b4bfef3103..6043f11b28 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_spd.h
+++ b/drivers/ddr/marvell/a38x/mv_ddr_spd.h
@@ -40,7 +40,10 @@
*/
union mv_ddr_spd_data {
unsigned char all_bytes[MV_DDR_SPD_DATA_BLOCK0_SIZE +
- MV_DDR_SPD_DATA_BLOCK1M_SIZE];
+ MV_DDR_SPD_DATA_BLOCK1M_SIZE +
+ MV_DDR_SPD_DATA_BLOCK1H_SIZE +
+ MV_DDR_SPD_DATA_BLOCK2E_SIZE +
+ MV_DDR_SPD_DATA_BLOCK2M_SIZE];
struct {
/* block 0 */
union { /* num of bytes used/num of bytes in spd device/crc coverage */
@@ -271,6 +274,9 @@ union mv_ddr_spd_data {
} bit_fields;
} byte_131;
unsigned char bytes_132_191[60]; /* reserved; all 0s */
+ unsigned char bytes_192_255[MV_DDR_SPD_DATA_BLOCK1H_SIZE];
+ unsigned char bytes_256_319[MV_DDR_SPD_DATA_BLOCK2E_SIZE];
+ unsigned char bytes_320_383[MV_DDR_SPD_DATA_BLOCK2M_SIZE];
} byte_fields;
};
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
index dc6977c334..10b0d45b35 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
+++ b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
@@ -78,22 +78,7 @@ enum suspend_wakeup_status {
* set '-2'
* If suspend to RAM is not supported set '-1'
*/
-#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
-#ifdef CONFIG_ARMADA_38X
-#define MV_BOARD_WAKEUP_GPIO_INFO { \
- {A38X_CUSTOMER_BOARD_ID0, -1 }, \
- {A38X_CUSTOMER_BOARD_ID0, -1 }, \
-};
-#else
-#define MV_BOARD_WAKEUP_GPIO_INFO { \
- {A39X_CUSTOMER_BOARD_ID0, -1 }, \
- {A39X_CUSTOMER_BOARD_ID0, -1 }, \
-};
-#endif /* CONFIG_ARMADA_38X */
-
-#else
-#ifdef CONFIG_ARMADA_38X
#define MV_BOARD_WAKEUP_GPIO_INFO { \
{RD_NAS_68XX_ID, -2 }, \
{DB_68XX_ID, -1 }, \
@@ -103,13 +88,6 @@ enum suspend_wakeup_status {
{DB_BP_6821_ID, -2 }, \
{DB_AMC_6820_ID, -2 }, \
};
-#else
-#define MV_BOARD_WAKEUP_GPIO_INFO { \
- {A39X_RD_69XX_ID, -1 }, \
- {A39X_DB_69XX_ID, -1 }, \
-};
-#endif /* CONFIG_ARMADA_38X */
-#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
enum suspend_wakeup_status mv_ddr_sys_env_suspend_wakeup_check(void);
u32 mv_ddr_sys_env_get_cs_ena_from_reg(void);
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.c b/drivers/ddr/marvell/a38x/mv_ddr_topology.c
index 09840b1e70..2db6283c23 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_topology.c
+++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c
@@ -127,6 +127,11 @@ int mv_ddr_topology_map_update(void)
speed_bin_index = iface_params->speed_bin_index;
freq = iface_params->memory_freq;
+ if (tm->twin_die_combined == COMBINED) {
+ iface_params->bus_width = MV_DDR_DEV_WIDTH_8BIT;
+ iface_params->memory_size -= 1;
+ }
+
if (iface_params->cas_l == 0)
iface_params->cas_l = mv_ddr_cl_val_get(speed_bin_index, freq);
@@ -144,6 +149,9 @@ unsigned short mv_ddr_bus_bit_mask_get(void)
unsigned int octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
if (tm->cfg_src == MV_DDR_CFG_SPD) {
+ if (tm->bus_act_mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK)
+ tm->spd_data.byte_fields.byte_13.bit_fields.primary_bus_width = MV_DDR_PRI_BUS_WIDTH_32;
+
enum mv_ddr_pri_bus_width pri_bus_width = mv_ddr_spd_pri_bus_width_get(&tm->spd_data);
enum mv_ddr_bus_width_ext bus_width_ext = mv_ddr_spd_bus_width_ext_get(&tm->spd_data);
@@ -151,7 +159,7 @@ unsigned short mv_ddr_bus_bit_mask_get(void)
case MV_DDR_PRI_BUS_WIDTH_16:
pri_and_ext_bus_width = BUS_MASK_16BIT;
break;
- case MV_DDR_PRI_BUS_WIDTH_32:
+ case MV_DDR_PRI_BUS_WIDTH_32: /*each bit represents byte, so 0xf-is means 4 bytes-32 bit*/
pri_and_ext_bus_width = BUS_MASK_32BIT;
break;
case MV_DDR_PRI_BUS_WIDTH_64:
@@ -245,7 +253,8 @@ static unsigned int mem_size[] = {
ADDR_SIZE_1GB,
ADDR_SIZE_2GB,
ADDR_SIZE_4GB,
- ADDR_SIZE_8GB
+ ADDR_SIZE_8GB,
+ ADDR_SIZE_16GB
/* TODO: add capacity up to 256GB */
};
@@ -277,7 +286,6 @@ unsigned long long mv_ddr_mem_sz_per_cs_get(void)
mem_sz_per_cs = (unsigned long long)mem_size[iface_params->memory_size] *
(unsigned long long)sphys /
(unsigned long long)sphys_per_dunit;
-
return mem_sz_per_cs;
}
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h
index 4fca47689f..1cb69ad085 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h
+++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h
@@ -179,7 +179,9 @@ enum mv_ddr_dic_evalue {
/* phy electrical configuration values */
enum mv_ddr_ohm_evalue {
+ MV_DDR_OHM_20 = 20,/*relevant for Synopsys C/A Drive strength only*/
MV_DDR_OHM_30 = 30,
+ MV_DDR_OHM_40 = 40,/*relevant for Synopsys C/A Drive strength only*/
MV_DDR_OHM_48 = 48,
MV_DDR_OHM_60 = 60,
MV_DDR_OHM_80 = 80,
diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c
index 5fb9e216d3..7bc6268293 100644
--- a/drivers/ddr/marvell/a38x/xor.c
+++ b/drivers/ddr/marvell/a38x/xor.c
@@ -340,18 +340,16 @@ void ddr3_new_tip_ecc_scrub(void)
{
u32 cs_c, max_cs;
u32 cs_ena = 0;
- uint64_t total_mem_size, cs_mem_size = 0;
+ uint64_t total_mem_size, cs_mem_size_mb = 0, cs_mem_size = 0;
printf("DDR Training Sequence - Start scrubbing\n");
max_cs = mv_ddr_cs_num_get();
for (cs_c = 0; cs_c < max_cs; cs_c++)
cs_ena |= 1 << cs_c;
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
/* all chip-selects are of same size */
- ddr3_calc_mem_cs_size(0, &cs_mem_size);
-#endif
-
+ ddr3_calc_mem_cs_size(0, &cs_mem_size_mb);
+ cs_mem_size = cs_mem_size_mb * _1M;
mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0);
total_mem_size = max_cs * cs_mem_size;
mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef);
diff --git a/drivers/ddr/marvell/axp/ddr3_dfs.c b/drivers/ddr/marvell/axp/ddr3_dfs.c
index b58c0fe01e..2a4596680b 100644
--- a/drivers/ddr/marvell/axp/ddr3_dfs.c
+++ b/drivers/ddr/marvell/axp/ddr3_dfs.c
@@ -42,8 +42,8 @@ extern u8 div_ratio[CLK_VCO][CLK_DDR];
extern void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps);
#else
extern u16 odt_dynamic[ODT_OPT][MAX_CS];
-extern u8 div_ratio1to1[CLK_CPU][CLK_DDR];
-extern u8 div_ratio2to1[CLK_CPU][CLK_DDR];
+extern u8 div_ratio1to1[CLK_VCO][CLK_DDR];
+extern u8 div_ratio2to1[CLK_VCO][CLK_DDR];
#endif
extern u16 odt_static[ODT_OPT][MAX_CS];
diff --git a/drivers/ddr/marvell/axp/ddr3_sdram.c b/drivers/ddr/marvell/axp/ddr3_sdram.c
index 3a266c6de4..0b150b20f3 100644
--- a/drivers/ddr/marvell/axp/ddr3_sdram.c
+++ b/drivers/ddr/marvell/axp/ddr3_sdram.c
@@ -21,7 +21,7 @@ extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
#if defined(MV88F78X60)
extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN];
#endif
-extern u32 pbs_dq_mapping[PUP_NUM_64BIT][DQ_NUM];
+extern u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM];
#if defined(MV88F78X60) || defined(MV88F672X)
/* PBS locked dq (per pup) */
diff --git a/drivers/ddr/marvell/axp/xor.c b/drivers/ddr/marvell/axp/xor.c
index 17bfe6a7bf..76aea96682 100644
--- a/drivers/ddr/marvell/axp/xor.c
+++ b/drivers/ddr/marvell/axp/xor.c
@@ -152,8 +152,8 @@ static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
return MV_OK;
}
-int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high,
- u32 init_val_low)
+int mv_xor_mem_init(u32 chan, u32 start_ptr, unsigned long long block_size,
+ u32 init_val_high, u32 init_val_low)
{
u32 tmp;
diff --git a/drivers/ddr/marvell/axp/xor.h b/drivers/ddr/marvell/axp/xor.h
index 97d1056432..a7c6ae840c 100644
--- a/drivers/ddr/marvell/axp/xor.h
+++ b/drivers/ddr/marvell/axp/xor.h
@@ -64,7 +64,7 @@ int mv_xor_state_get(u32 chan);
void mv_sys_xor_init(MV_DRAM_INFO *dram_info);
void mv_sys_xor_finish(void);
int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr);
-int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high,
- u32 init_val_low);
+int mv_xor_mem_init(u32 chan, u32 start_ptr, unsigned long long block_size,
+ u32 init_val_high, u32 init_val_low);
#endif /* __XOR_H */
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index a17e488714..2d1836a80e 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -72,6 +72,15 @@ config FASTBOOT_FLASH
the downloaded image to a non-volatile storage device. Define
this to enable the "fastboot flash" command.
+config FASTBOOT_UUU_SUPPORT
+ bool "Enable FASTBOOT i.MX UUU special command"
+ default n
+ help
+ The fastboot protocol includes "UCmd" and "ACmd" command.
+ Be aware that you provide full access to any U-Boot command,
+ including working with memory and may open a huge backdoor,
+ when enabling this option.
+
choice
prompt "Flash provider for FASTBOOT"
depends on FASTBOOT_FLASH
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index 41fc8d7904..3a5db5b08f 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -49,6 +49,11 @@ static void oem_partconf(char *, char *);
static void oem_bootbus(char *, char *);
#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+static void run_ucmd(char *, char *);
+static void run_acmd(char *, char *);
+#endif
+
static const struct {
const char *command;
void (*dispatch)(char *cmd_parameter, char *response);
@@ -117,6 +122,16 @@ static const struct {
.dispatch = oem_bootbus,
},
#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+ [FASTBOOT_COMMAND_UCMD] = {
+ .command = "UCmd",
+ .dispatch = run_ucmd,
+ },
+ [FASTBOOT_COMMAND_ACMD] = {
+ .command = "ACmd",
+ .dispatch = run_acmd,
+ },
+#endif
};
/**
@@ -327,6 +342,59 @@ static void erase(char *cmd_parameter, char *response)
}
#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+/**
+ * run_ucmd() - Execute the UCmd command
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void run_ucmd(char *cmd_parameter, char *response)
+{
+ if (!cmd_parameter) {
+ pr_err("missing slot suffix\n");
+ fastboot_fail("missing command", response);
+ return;
+ }
+
+ if (run_command(cmd_parameter, 0))
+ fastboot_fail("", response);
+ else
+ fastboot_okay(NULL, response);
+}
+
+static char g_a_cmd_buff[64];
+
+void fastboot_acmd_complete(void)
+{
+ run_command(g_a_cmd_buff, 0);
+}
+
+/**
+ * run_acmd() - Execute the ACmd command
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void run_acmd(char *cmd_parameter, char *response)
+{
+ if (!cmd_parameter) {
+ pr_err("missing slot suffix\n");
+ fastboot_fail("missing command", response);
+ return;
+ }
+
+ if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
+ pr_err("too long command\n");
+ fastboot_fail("too long command", response);
+ return;
+ }
+
+ strcpy(g_a_cmd_buff, cmd_parameter);
+ fastboot_okay(NULL, response);
+}
+#endif
+
/**
* reboot_bootloader() - Sets reboot bootloader flag.
*
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index 50532acb84..8e74e50e91 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -28,30 +28,9 @@ struct fb_mmc_sparse {
struct blk_desc *dev_desc;
};
-static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
- const char *name, struct disk_partition *info)
-{
- int ret;
-
- ret = part_get_info_by_name(dev_desc, name, info);
- if (ret < 0) {
- /* strlen("fastboot_partition_alias_") + PART_NAME_LEN + 1 */
- char env_alias_name[25 + PART_NAME_LEN + 1];
- char *aliased_part_name;
-
- /* check for alias */
- strcpy(env_alias_name, "fastboot_partition_alias_");
- strncat(env_alias_name, name, PART_NAME_LEN);
- aliased_part_name = env_get(env_alias_name);
- if (aliased_part_name != NULL)
- ret = part_get_info_by_name(dev_desc,
- aliased_part_name, info);
- }
- return ret;
-}
-
static int raw_part_get_info_by_name(struct blk_desc *dev_desc,
- const char *name, struct disk_partition *info, int *mmcpart)
+ const char *name,
+ struct disk_partition *info)
{
/* strlen("fastboot_raw_partition_") + PART_NAME_LEN + 1 */
char env_desc_name[23 + PART_NAME_LEN + 1];
@@ -85,13 +64,65 @@ static int raw_part_get_info_by_name(struct blk_desc *dev_desc,
strncpy((char *)info->name, name, PART_NAME_LEN);
if (raw_part_desc) {
- if (strcmp(strsep(&raw_part_desc, " "), "mmcpart") == 0)
- *mmcpart = simple_strtoul(raw_part_desc, NULL, 0);
+ if (strcmp(strsep(&raw_part_desc, " "), "mmcpart") == 0) {
+ ulong mmcpart = simple_strtoul(raw_part_desc, NULL, 0);
+ int ret = blk_dselect_hwpart(dev_desc, mmcpart);
+
+ if (ret)
+ return ret;
+ }
}
return 0;
}
+static int do_get_part_info(struct blk_desc **dev_desc, const char *name,
+ struct disk_partition *info)
+{
+ int ret;
+
+ /* First try partition names on the default device */
+ *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ if (*dev_desc) {
+ ret = part_get_info_by_name(*dev_desc, name, info);
+ if (ret >= 0)
+ return ret;
+
+ /* Then try raw partitions */
+ ret = raw_part_get_info_by_name(*dev_desc, name, info);
+ if (ret >= 0)
+ return ret;
+ }
+
+ /* Then try dev.hwpart:part */
+ ret = part_get_info_by_dev_and_name_or_num("mmc", name, dev_desc,
+ info, true);
+ return ret;
+}
+
+static int part_get_info_by_name_or_alias(struct blk_desc **dev_desc,
+ const char *name,
+ struct disk_partition *info)
+{
+ int ret;
+
+ ret = do_get_part_info(dev_desc, name, info);
+ if (ret < 0) {
+ /* strlen("fastboot_partition_alias_") + PART_NAME_LEN + 1 */
+ char env_alias_name[25 + PART_NAME_LEN + 1];
+ char *aliased_part_name;
+
+ /* check for alias */
+ strcpy(env_alias_name, "fastboot_partition_alias_");
+ strncat(env_alias_name, name, PART_NAME_LEN);
+ aliased_part_name = env_get(env_alias_name);
+ if (aliased_part_name != NULL)
+ ret = do_get_part_info(dev_desc, aliased_part_name,
+ info);
+ }
+ return ret;
+}
+
/**
* fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE
*
@@ -424,28 +455,49 @@ int fastboot_mmc_get_part_info(const char *part_name,
struct blk_desc **dev_desc,
struct disk_partition *part_info, char *response)
{
- int r = 0;
- int mmcpart;
+ int ret;
- *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
- if (!*dev_desc) {
- fastboot_fail("block device not found", response);
- return -ENOENT;
- }
if (!part_name || !strcmp(part_name, "")) {
fastboot_fail("partition not given", response);
return -ENOENT;
}
- if (raw_part_get_info_by_name(*dev_desc, part_name, part_info, &mmcpart) < 0) {
- r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info);
- if (r < 0) {
- fastboot_fail("partition not found", response);
- return r;
+ ret = part_get_info_by_name_or_alias(dev_desc, part_name, part_info);
+ if (ret < 0) {
+ switch (ret) {
+ case -ENOSYS:
+ case -EINVAL:
+ fastboot_fail("invalid partition or device", response);
+ break;
+ case -ENODEV:
+ fastboot_fail("no such device", response);
+ break;
+ case -ENOENT:
+ fastboot_fail("no such partition", response);
+ break;
+ case -EPROTONOSUPPORT:
+ fastboot_fail("unknown partition table type", response);
+ break;
+ default:
+ fastboot_fail("unanticipated error", response);
+ break;
}
}
- return r;
+ return ret;
+}
+
+static struct blk_desc *fastboot_mmc_get_dev(char *response)
+{
+ struct blk_desc *ret = blk_get_dev("mmc",
+ CONFIG_FASTBOOT_FLASH_MMC_DEV);
+
+ if (!ret || ret->type == DEV_TYPE_UNKNOWN) {
+ pr_err("invalid mmc device\n");
+ fastboot_fail("invalid mmc device", response);
+ return NULL;
+ }
+ return ret;
}
/**
@@ -461,24 +513,20 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
{
struct blk_desc *dev_desc;
struct disk_partition info;
- int mmcpart = 0;
-
- dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
- if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
- pr_err("invalid mmc device\n");
- fastboot_fail("invalid mmc device", response);
- return;
- }
#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
- fb_mmc_boot_ops(dev_desc, download_buffer, 1,
- download_bytes, response);
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (dev_desc)
+ fb_mmc_boot_ops(dev_desc, download_buffer, 1,
+ download_bytes, response);
return;
}
if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
- fb_mmc_boot_ops(dev_desc, download_buffer, 2,
- download_bytes, response);
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (dev_desc)
+ fb_mmc_boot_ops(dev_desc, download_buffer, 1,
+ download_bytes, response);
return;
}
#endif
@@ -490,6 +538,10 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0 ||
strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
#endif
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (!dev_desc)
+ return;
+
printf("%s: updating MBR, Primary and Backup GPT(s)\n",
__func__);
if (is_valid_gpt_buf(dev_desc, download_buffer)) {
@@ -513,6 +565,10 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
#if CONFIG_IS_ENABLED(DOS_PARTITION)
if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (!dev_desc)
+ return;
+
printf("%s: updating MBR\n", __func__);
if (is_valid_dos_buf(download_buffer)) {
printf("%s: invalid MBR - refusing to write to flash\n",
@@ -535,23 +591,16 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
#ifdef CONFIG_ANDROID_BOOT_IMAGE
if (strncasecmp(cmd, "zimage", 6) == 0) {
- fb_mmc_update_zimage(dev_desc, download_buffer,
- download_bytes, response);
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (dev_desc)
+ fb_mmc_update_zimage(dev_desc, download_buffer,
+ download_bytes, response);
return;
}
#endif
- if (raw_part_get_info_by_name(dev_desc, cmd, &info, &mmcpart) == 0) {
- if (blk_dselect_hwpart(dev_desc, mmcpart)) {
- pr_err("Failed to select hwpart\n");
- fastboot_fail("Failed to select hwpart", response);
- return;
- }
- } else if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
- pr_err("cannot find partition: '%s'\n", cmd);
- fastboot_fail("cannot find partition", response);
+ if (fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
return;
- }
if (is_sparse_image(download_buffer)) {
struct fb_mmc_sparse sparse_priv;
@@ -593,30 +642,20 @@ void fastboot_mmc_erase(const char *cmd, char *response)
struct disk_partition info;
lbaint_t blks, blks_start, blks_size, grp_size;
struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
- int mmcpart = 0;
-
- if (mmc == NULL) {
- pr_err("invalid mmc device\n");
- fastboot_fail("invalid mmc device", response);
- return;
- }
-
- dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
- if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
- pr_err("invalid mmc device\n");
- fastboot_fail("invalid mmc device", response);
- return;
- }
#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
/* erase EMMC boot1 */
- fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (dev_desc)
+ fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
return;
}
if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
/* erase EMMC boot2 */
- fb_mmc_boot_ops(dev_desc, NULL, 2, 0, response);
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (dev_desc)
+ fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
return;
}
#endif
@@ -624,6 +663,10 @@ void fastboot_mmc_erase(const char *cmd, char *response)
#ifdef CONFIG_FASTBOOT_MMC_USER_SUPPORT
if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
/* erase EMMC userdata */
+ dev_desc = fastboot_mmc_get_dev(response);
+ if (!dev_desc)
+ return;
+
if (fb_mmc_erase_mmc_hwpart(dev_desc))
fastboot_fail("Failed to erase EMMC_USER", response);
else
@@ -632,17 +675,8 @@ void fastboot_mmc_erase(const char *cmd, char *response)
}
#endif
- if (raw_part_get_info_by_name(dev_desc, cmd, &info, &mmcpart) == 0) {
- if (blk_dselect_hwpart(dev_desc, mmcpart)) {
- pr_err("Failed to select hwpart\n");
- fastboot_fail("Failed to select hwpart", response);
- return;
- }
- } else if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
- pr_err("cannot find partition: '%s'\n", cmd);
- fastboot_fail("cannot find partition", response);
+ if (fastboot_mmc_get_part_info(cmd, &dev_desc, &info, response) < 0)
return;
- }
/* Align blocks to erase group size to avoid erasing other partitions */
grp_size = mmc->erase_grp_size;
diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c
index 3f4b04a4ae..ea35e7e09e 100644
--- a/drivers/firmware/scmi/mailbox_agent.c
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -3,13 +3,15 @@
* Copyright (C) 2020 Linaro Limited.
*/
+#define LOG_CATEGORY UCLASS_SCMI_AGENT
+
#include <common.h>
#include <dm.h>
-#include <dm/device_compat.h>
#include <errno.h>
#include <mailbox.h>
#include <scmi_agent.h>
#include <scmi_agent-uclass.h>
+#include <dm/device_compat.h>
#include <dm/devres.h>
#include <linux/compat.h>
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 35de68c75d..97a5dace15 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -3,6 +3,8 @@
* Copyright (C) 2020, Linaro Limited
*/
+#define LOG_CATEGORY UCLASS_SCMI_AGENT
+
#include <common.h>
#include <dm.h>
#include <malloc.h>
diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c
index 1a6fafbf53..69239a198f 100644
--- a/drivers/firmware/scmi/sandbox-scmi_devices.c
+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c
@@ -3,6 +3,8 @@
* Copyright (C) 2020, Linaro Limited
*/
+#define LOG_CATEGORY UCLASS_MISC
+
#include <common.h>
#include <clk.h>
#include <dm.h>
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 516e690ac2..527163b5ce 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -3,13 +3,14 @@
* Copyright (C) 2020 Linaro Limited.
*/
+#define LOG_CATEGORY UCLASS_SCMI_AGENT
+
#include <common.h>
#include <dm.h>
-#include <dm/device_compat.h>
#include <errno.h>
#include <scmi_agent-uclass.h>
#include <scmi_protocols.h>
-
+#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <linux/compat.h>
diff --git a/drivers/firmware/scmi/smccc_agent.c b/drivers/firmware/scmi/smccc_agent.c
index 64d0929f69..f185891e8f 100644
--- a/drivers/firmware/scmi/smccc_agent.c
+++ b/drivers/firmware/scmi/smccc_agent.c
@@ -3,12 +3,15 @@
* Copyright (C) 2020 Linaro Limited.
*/
+#define LOG_CATEGORY UCLASS_SCMI_AGENT
+
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <scmi_agent.h>
#include <scmi_agent-uclass.h>
#include <dm/devres.h>
+#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <linux/arm-smccc.h>
#include <linux/compat.h>
diff --git a/drivers/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c
index d25478796a..60b9d499b7 100644
--- a/drivers/firmware/scmi/smt.c
+++ b/drivers/firmware/scmi/smt.c
@@ -4,6 +4,8 @@
* Copyright (C) 2019-2020 Linaro Limited.
*/
+#define LOG_CATEGORY UCLASS_SCMI_AGENT
+
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 425b52a926..dc0b3dd31b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -33,7 +33,7 @@ config FPGA_CYCLON2
config FPGA_INTEL_SDM_MAILBOX
bool "Enable Intel FPGA Full Reconfiguration SDM Mailbox driver"
- depends on TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX
+ depends on TARGET_SOCFPGA_SOC64
select FPGA_ALTERA
help
Say Y here to enable the Intel FPGA Full Reconfig SDM Mailbox driver
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c
index a11e485525..2de40109a8 100644
--- a/drivers/fpga/zynqpl.c
+++ b/drivers/fpga/zynqpl.c
@@ -315,7 +315,7 @@ static u32 *zynq_align_dma_buffer(u32 *buf, u32 len, u32 swap)
if (new_buf > buf) {
debug("%s: Aligned buffer is after buffer start\n",
__func__);
- new_buf -= ARCH_DMA_MINALIGN;
+ new_buf = (u32 *)((u32)new_buf - ARCH_DMA_MINALIGN);
}
printf("%s: Align buffer at %x to %x(swap %d)\n", __func__,
(u32)buf, (u32)new_buf, swap);
diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c
index c733603289..f7ffd8926a 100644
--- a/drivers/gpio/mpc8xxx_gpio.c
+++ b/drivers/gpio/mpc8xxx_gpio.c
@@ -20,7 +20,7 @@ struct mpc8xxx_gpio_data {
/* The bank's register base in memory */
struct ccsr_gpio __iomem *base;
/* The address of the registers; used to identify the bank */
- ulong addr;
+ phys_addr_t addr;
/* The GPIO count of the bank */
uint gpio_count;
/* The GPDAT register cannot be used to determine the value of output
@@ -181,7 +181,7 @@ static int mpc8xxx_gpio_of_to_plat(struct udevice *dev)
if (dev_read_bool(dev, "little-endian"))
data->little_endian = true;
- plat->addr = (ulong)dev_read_addr_size_index(dev, 0, (fdt_size_t *)&plat->size);
+ plat->addr = dev_read_addr_size_index(dev, 0, (fdt_size_t *)&plat->size);
plat->ngpios = dev_read_u32_default(dev, "ngpios", 32);
return 0;
@@ -220,7 +220,8 @@ static int mpc8xxx_gpio_probe(struct udevice *dev)
mpc8xxx_gpio_plat_to_priv(dev);
- snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
+ snprintf(name, sizeof(name), "MPC@%.8llx",
+ (unsigned long long)data->addr);
str = strdup(name);
if (!str)
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index db3c04fa6e..a650dd69b8 100644
--- a/drivers/i2c/i2c-cdns.c
+++ b/drivers/i2c/i2c-cdns.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/io.h>
#include <linux/errno.h>
+#include <dm/device_compat.h>
#include <dm/root.h>
#include <i2c.h>
#include <fdtdec.h>
@@ -481,6 +482,12 @@ static int cdns_i2c_of_to_plat(struct udevice *dev)
i2c_bus->input_freq = clk_get_rate(&clk);
+ ret = clk_enable(&clk);
+ if (ret) {
+ dev_err(dev, "failed to enable clock\n");
+ return ret;
+ }
+
return 0;
}
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index e0e132698e..6a9403dc00 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -43,6 +43,12 @@
#include "mmc_private.h"
#endif
+#ifndef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
+#ifdef CONFIG_FSL_USDHC
+#define ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE 1
+#endif
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
#define SDHCI_IRQ_EN_BITS (IRQSTATEN_CC | IRQSTATEN_TC | \
@@ -1706,6 +1712,7 @@ static struct esdhc_soc_data usdhc_imx8qm_data = {
};
static const struct udevice_id fsl_esdhc_ids[] = {
+ { .compatible = "fsl,imx51-esdhc", },
{ .compatible = "fsl,imx53-esdhc", },
{ .compatible = "fsl,imx6ul-usdhc", },
{ .compatible = "fsl,imx6sx-usdhc", },
diff --git a/drivers/mmc/iproc_sdhci.c b/drivers/mmc/iproc_sdhci.c
index 6e4f527e5d..11d86ad658 100644
--- a/drivers/mmc/iproc_sdhci.c
+++ b/drivers/mmc/iproc_sdhci.c
@@ -10,8 +10,11 @@
#include <malloc.h>
#include <sdhci.h>
#include <asm/global_data.h>
+#include "mmc_private.h"
#include <linux/delay.h>
+#define MAX_TUNING_LOOP 40
+
DECLARE_GLOBAL_DATA_PTR;
struct sdhci_iproc_host {
@@ -140,17 +143,89 @@ static void sdhci_iproc_writeb(struct sdhci_host *host, u8 val, int reg)
static int sdhci_iproc_set_ios_post(struct sdhci_host *host)
{
- u32 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ struct mmc *mmc = (struct mmc *)host->mmc;
+ u32 ctrl;
+
+ if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ ctrl |= SDHCI_CTRL_VDD_180;
+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ }
- /* Reset UHS mode bits */
- ctrl &= ~SDHCI_CTRL_UHS_MASK;
+ sdhci_set_uhs_timing(host);
+ return 0;
+}
- if (host->mmc->ddr_mode)
- ctrl |= UHS_DDR50_BUS_SPEED;
+static void sdhci_start_tuning(struct sdhci_host *host)
+{
+ u32 ctrl;
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ ctrl |= SDHCI_CTRL_EXEC_TUNING;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
- return 0;
+ sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
+ sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_end_tuning(struct sdhci_host *host)
+{
+ /* Enable only interrupts served by the SD controller */
+ sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
+ SDHCI_INT_ENABLE);
+ /* Mask all sdhci interrupt sources */
+ sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
+}
+
+static int sdhci_iproc_execute_tuning(struct mmc *mmc, u8 opcode)
+{
+ struct mmc_cmd cmd;
+ u32 ctrl;
+ u32 blocksize = SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 64);
+ struct sdhci_host *host = dev_get_priv(mmc->dev);
+ char tuning_loop_counter = MAX_TUNING_LOOP;
+ int ret = 0;
+
+ sdhci_start_tuning(host);
+
+ cmd.cmdidx = opcode;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = 0;
+
+ if (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200 && mmc->bus_width == 8)
+ blocksize = SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 128);
+
+ sdhci_writew(host, blocksize, SDHCI_BLOCK_SIZE);
+ sdhci_writew(host, 1, SDHCI_BLOCK_COUNT);
+ sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
+
+ do {
+ mmc_send_cmd(mmc, &cmd, NULL);
+ if (opcode == MMC_CMD_SEND_TUNING_BLOCK)
+ /*
+ * For tuning command, do not do busy loop. As tuning
+ * is happening (CLK-DATA latching for setup/hold time
+ * requirements), give time to complete
+ */
+ udelay(1);
+
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+ if (tuning_loop_counter-- == 0)
+ break;
+
+ } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
+
+ if (tuning_loop_counter < 0 || (!(ctrl & SDHCI_CTRL_TUNED_CLK))) {
+ ctrl &= ~(SDHCI_CTRL_TUNED_CLK | SDHCI_CTRL_EXEC_TUNING);
+ sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL2);
+ printf("%s:Tuning failed, opcode = 0x%02x\n", __func__, opcode);
+ ret = -EIO;
+ }
+
+ sdhci_end_tuning(host);
+
+ return ret;
}
static struct sdhci_ops sdhci_platform_ops = {
@@ -163,6 +238,7 @@ static struct sdhci_ops sdhci_platform_ops = {
.write_b = sdhci_iproc_writeb,
#endif
.set_ios_post = sdhci_iproc_set_ios_post,
+ .platform_execute_tuning = sdhci_iproc_execute_tuning,
};
struct iproc_sdhci_plat {
@@ -190,9 +266,7 @@ static int iproc_sdhci_probe(struct udevice *dev)
host->name = dev->name;
host->ioaddr = dev_read_addr_ptr(dev);
- host->voltages = MMC_VDD_165_195 |
- MMC_VDD_32_33 | MMC_VDD_33_34;
- host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B;
+ host->quirks = SDHCI_QUIRK_BROKEN_R1B;
host->host_caps = MMC_MODE_DDR_52MHz;
host->index = fdtdec_get_uint(gd->fdt_blob, node, "index", 0);
host->ops = &sdhci_platform_ops;
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index 3b9c12266a..48a764be82 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -1639,7 +1639,8 @@ static int msdc_drv_probe(struct udevice *dev)
else
cfg->f_min = host->src_clk_freq / (4 * 4095);
- cfg->f_max = host->src_clk_freq;
+ if (cfg->f_max < cfg->f_min || cfg->f_max > host->src_clk_freq)
+ cfg->f_max = host->src_clk_freq;
cfg->b_max = 1024;
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c
index 8a2391d651..18ba020aac 100644
--- a/drivers/mmc/sandbox_mmc.c
+++ b/drivers/mmc/sandbox_mmc.c
@@ -17,6 +17,17 @@ struct sandbox_mmc_plat {
struct mmc mmc;
};
+#define MMC_CSIZE 0
+#define MMC_CMULT 8 /* 8 because the card is high-capacity */
+#define MMC_BL_LEN_SHIFT 10
+#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT)
+#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \
+ * MMC_BL_LEN) /* 1 MiB */
+
+struct sandbox_mmc_priv {
+ u8 buf[MMC_CAPACITY];
+};
+
/**
* sandbox_mmc_send_cmd() - Emulate SD commands
*
@@ -26,6 +37,10 @@ struct sandbox_mmc_plat {
static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
+ struct sandbox_mmc_priv *priv = dev_get_priv(dev);
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ static ulong erase_start, erase_end;
+
switch (cmd->cmdidx) {
case MMC_CMD_ALL_SEND_CID:
memset(cmd->response, '\0', sizeof(cmd->response));
@@ -44,8 +59,9 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
break;
case MMC_CMD_SEND_CSD:
cmd->response[0] = 0;
- cmd->response[1] = 10 << 16; /* 1 << block_len */
- cmd->response[2] = 0;
+ cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) |
+ ((MMC_CSIZE >> 16) & 0x3f);
+ cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
cmd->response[3] = 0;
break;
case SD_CMD_SWITCH_FUNC: {
@@ -59,13 +75,27 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
break;
}
case MMC_CMD_READ_SINGLE_BLOCK:
- memset(data->dest, '\0', data->blocksize);
- break;
case MMC_CMD_READ_MULTIPLE_BLOCK:
- strcpy(data->dest, "this is a test");
+ memcpy(data->dest, &priv->buf[cmd->cmdarg * data->blocksize],
+ data->blocks * data->blocksize);
+ break;
+ case MMC_CMD_WRITE_SINGLE_BLOCK:
+ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+ memcpy(&priv->buf[cmd->cmdarg * data->blocksize], data->src,
+ data->blocks * data->blocksize);
break;
case MMC_CMD_STOP_TRANSMISSION:
break;
+ case SD_CMD_ERASE_WR_BLK_START:
+ erase_start = cmd->cmdarg;
+ break;
+ case SD_CMD_ERASE_WR_BLK_END:
+ erase_end = cmd->cmdarg;
+ break;
+ case MMC_CMD_ERASE:
+ memset(&priv->buf[erase_start * mmc->write_bl_len], '\0',
+ (erase_end - erase_start + 1) * mmc->write_bl_len);
+ break;
case SD_CMD_APP_SEND_OP_COND:
cmd->response[0] = OCR_BUSY | OCR_HCS;
cmd->response[1] = 0;
@@ -148,5 +178,6 @@ U_BOOT_DRIVER(mmc_sandbox) = {
.bind = sandbox_mmc_bind,
.unbind = sandbox_mmc_unbind,
.probe = sandbox_mmc_probe,
- .plat_auto = sizeof(struct sandbox_mmc_plat),
+ .priv_auto = sizeof(struct sandbox_mmc_priv),
+ .plat_auto = sizeof(struct sandbox_mmc_plat),
};
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index d9ad0ff199..b79c4021b6 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -577,7 +577,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
debug("%s: CLK %ld\n", __func__, clock);
ret = clk_enable(&clk);
- if (ret && ret != -ENOSYS) {
+ if (ret) {
dev_err(dev, "failed to enable clock\n");
return ret;
}
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index 219efdc895..090834a495 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) "nand: " fmt
#include <common.h>
+#include <watchdog.h>
#ifndef __UBOOT__
#include <linux/compat.h>
#include <linux/module.h>
@@ -172,6 +173,7 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
nanddev_offs_to_pos(nand, einfo->addr, &pos);
nanddev_offs_to_pos(nand, einfo->addr + einfo->len - 1, &last);
while (nanddev_pos_cmp(&pos, &last) <= 0) {
+ WATCHDOG_RESET();
ret = nanddev_erase(nand, &pos);
if (ret) {
einfo->fail_addr = nanddev_pos_to_offs(nand, &pos);
diff --git a/drivers/mtd/nand/raw/cortina_nand.c b/drivers/mtd/nand/raw/cortina_nand.c
index 12bd1ded83..81fa8788a4 100644
--- a/drivers/mtd/nand/raw/cortina_nand.c
+++ b/drivers/mtd/nand/raw/cortina_nand.c
@@ -546,7 +546,7 @@ static int ca_do_bch_correction(struct nand_chip *chip,
struct nand_drv *info =
(struct nand_drv *)nand_get_controller_data(chip);
unsigned int reg_v, err_loc0, err_loc1;
- int k, max_bitflips;
+ int k, max_bitflips = 0;
for (k = 0; k < (err_num + 1) / 2; k++) {
reg_v = readl(&info->reg->flash_nf_bch_error_loc01 + k);
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 68ef5d1af8..e5330958c7 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -22,6 +22,7 @@
#else
#include <common.h>
#include <errno.h>
+#include <watchdog.h>
#include <spi.h>
#include <spi-mem.h>
#include <dm/device_compat.h>
@@ -578,6 +579,7 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
#endif
nanddev_io_for_each_page(nand, from, ops, &iter) {
+ WATCHDOG_RESET();
ret = spinand_select_target(spinand, iter.req.pos.target);
if (ret)
break;
@@ -629,6 +631,7 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to,
#endif
nanddev_io_for_each_page(nand, to, ops, &iter) {
+ WATCHDOG_RESET();
ret = spinand_select_target(spinand, iter.req.pos.target);
if (ret)
break;
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
index 0b228dcb5b..a2c93486f4 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -17,9 +17,22 @@
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
-#define GD5FXGQ4XEXXG_REG_STATUS2 0xf0
+#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
+#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
-static SPINAND_OP_VARIANTS(read_cache_variants,
+#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
+
+/* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */
+static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
+static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
@@ -35,7 +48,7 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
SPINAND_PROG_LOAD(false, 0, NULL, 0));
-static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
+static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
@@ -47,7 +60,7 @@ static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
return 0;
}
-static int gd5fxgq4xexxg_ooblayout_free(struct mtd_info *mtd, int section,
+static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
@@ -64,7 +77,7 @@ static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
u8 status2;
- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4XEXXG_REG_STATUS2,
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
&status2);
int ret;
@@ -102,21 +115,67 @@ static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
return -EINVAL;
}
-static const struct mtd_ooblayout_ops gd5fxgq4xexxg_ooblayout = {
- .ecc = gd5fxgq4xexxg_ooblayout_ecc,
- .rfree = gd5fxgq4xexxg_ooblayout_free,
+static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ u8 status2;
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
+ &status2);
+ int ret;
+
+ switch (status & STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
+ /*
+ * Read status2 register to determine a more fine grained
+ * bit error status
+ */
+ ret = spi_mem_exec_op(spinand->slave, &op);
+ if (ret)
+ return ret;
+
+ /*
+ * 1 ... 4 bits are flipped (and corrected)
+ */
+ /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
+ return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = {
+ .ecc = gd5fxgqxxexxg_ooblayout_ecc,
+ .rfree = gd5fxgqxxexxg_ooblayout_free,
};
static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
- SPINAND_ECCINFO(&gd5fxgq4xexxg_ooblayout,
+ SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
gd5fxgq4xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ5UExxG", 0x51,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
+ gd5fxgq5xexxg_ecc_get_status)),
};
static int gigadevice_spinand_detect(struct spinand_device *spinand)
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index ef426dac02..e0efebc355 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -11,6 +11,7 @@
#include <common.h>
#include <log.h>
+#include <watchdog.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
@@ -566,6 +567,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
len = instr->len;
while (len) {
+ WATCHDOG_RESET();
#ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1250,6 +1252,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
for (i = 0; i < len; ) {
ssize_t written;
loff_t addr = to + i;
+ WATCHDOG_RESET();
/*
* If page_size is a power of two, the offset can be quickly
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 5bd5dd3003..2b57797954 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -108,6 +108,11 @@ const struct flash_info spi_nor_ids[] = {
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ INFO("gd25lq64c", 0xc86017, 0, 64 * 1024, 128,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
INFO("gd25q128", 0xc84018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
@@ -319,7 +324,10 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("w25q80bl", 0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q16cl", 0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q64cv", 0xef4017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { INFO("w25q128", 0xef4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("w25q128", 0xef4018, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
diff --git a/drivers/net/cortina_ni.c b/drivers/net/cortina_ni.c
index ee424d95bc..ef6ecd88b0 100644
--- a/drivers/net/cortina_ni.c
+++ b/drivers/net/cortina_ni.c
@@ -713,7 +713,7 @@ static int cortina_eth_recv(struct udevice *dev, int flags, uchar **packetp)
priv->rx_xram_end_adr);
memcpy(&packet_status, rx_xram_ptr,
- sizeof(rx_xram_ptr));
+ sizeof(*rx_xram_ptr));
if (packet_status.valid == 0) {
debug("%s: Invalid Packet !!, ", __func__);
debug("next_link=%d\n", next_link);
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 5cb02bb3a7..baf06a2ad8 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -129,6 +129,8 @@
#define ZYNQ_GEM_FREQUENCY_100 25000000UL
#define ZYNQ_GEM_FREQUENCY_1000 125000000UL
+#define RXCLK_EN BIT(0)
+
/* Device registers */
struct zynq_gem_regs {
u32 nwctrl; /* 0x0 - Network Control reg */
@@ -205,10 +207,12 @@ struct zynq_gem_priv {
struct phy_device *phydev;
ofnode phy_of_node;
struct mii_dev *bus;
- struct clk clk;
+ struct clk rx_clk;
+ struct clk tx_clk;
u32 max_speed;
bool int_pcs;
bool dma_64bit;
+ u32 clk_en_info;
};
static int phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
@@ -476,18 +480,25 @@ static int zynq_gem_init(struct udevice *dev)
break;
}
- ret = clk_set_rate(&priv->clk, clk_rate);
- if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
+ ret = clk_set_rate(&priv->tx_clk, clk_rate);
+ if (IS_ERR_VALUE(ret)) {
dev_err(dev, "failed to set tx clock rate\n");
return ret;
}
- ret = clk_enable(&priv->clk);
- if (ret && ret != -ENOSYS) {
+ ret = clk_enable(&priv->tx_clk);
+ if (ret) {
dev_err(dev, "failed to enable tx clock\n");
return ret;
}
+ if (priv->clk_en_info & RXCLK_EN) {
+ ret = clk_enable(&priv->rx_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable rx clock\n");
+ return ret;
+ }
+ }
setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
ZYNQ_GEM_NWCTRL_TXEN_MASK);
@@ -694,10 +705,18 @@ static int zynq_gem_probe(struct udevice *dev)
priv->tx_bd = (struct emac_bd *)bd_space;
priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
- ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
+ ret = clk_get_by_name(dev, "tx_clk", &priv->tx_clk);
if (ret < 0) {
- dev_err(dev, "failed to get clock\n");
- goto err1;
+ dev_err(dev, "failed to get tx_clock\n");
+ goto err2;
+ }
+
+ if (priv->clk_en_info & RXCLK_EN) {
+ ret = clk_get_by_name(dev, "rx_clk", &priv->rx_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to get rx_clock\n");
+ goto err2;
+ }
}
priv->bus = mdio_alloc();
@@ -711,14 +730,16 @@ static int zynq_gem_probe(struct udevice *dev)
ret = zynq_phy_init(dev);
if (ret)
- goto err2;
+ goto err3;
return ret;
+err3:
+ mdio_unregister(priv->bus);
err2:
- free(priv->rxbuffers);
-err1:
free(priv->tx_bd);
+err1:
+ free(priv->rxbuffers);
return ret;
}
@@ -792,11 +813,13 @@ static int zynq_gem_of_to_plat(struct udevice *dev)
(ulong)priv->iobase, (ulong)priv->mdiobase, priv->phyaddr,
phy_string_for_interface(priv->interface));
+ priv->clk_en_info = dev_get_driver_data(dev);
+
return 0;
}
static const struct udevice_id zynq_gem_ids[] = {
- { .compatible = "cdns,versal-gem" },
+ { .compatible = "cdns,versal-gem", .data = RXCLK_EN },
{ .compatible = "cdns,zynqmp-gem" },
{ .compatible = "cdns,zynq-gem" },
{ .compatible = "cdns,gem" },
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index e72a60c131..fc3327ec53 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -32,6 +32,8 @@ DECLARE_GLOBAL_DATA_PTR;
#include <asm/io.h>
#include <asm/fsl_pci.h>
+#define MAX_PCI_REGIONS 7
+
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
#define CONFIG_SYS_PCI_MEMORY_BUS 0
#endif
@@ -80,6 +82,9 @@ int fsl_setup_hose(struct pci_controller *hose, unsigned long addr)
/* Reset hose to make sure its in a clean state */
memset(hose, 0, sizeof(struct pci_controller));
+ hose->regions = (struct pci_region *)
+ calloc(1, MAX_PCI_REGIONS * sizeof(struct pci_region));
+
pci_setup_indirect(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
return fsl_is_pci_agent(hose);
diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index 8713b88461..3b9309f52c 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -42,6 +42,10 @@
#define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8
#define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4)
#define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
+#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE 0x2
+#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE_SHIFT 5
+#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE 0x2
+#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12
#define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
#define PCIE_CORE_LINK_TRAINING BIT(5)
#define PCIE_CORE_ERR_CAPCTL_REG 0x118
@@ -101,6 +105,7 @@
#define LTSSM_SHIFT 24
#define LTSSM_MASK 0x3f
#define LTSSM_L0 0x10
+#define VENDOR_ID_REG (LMI_BASE_ADDR + 0x44)
/* PCIe core controller registers */
#define CTRL_CORE_BASE_ADDR 0x18000
@@ -525,6 +530,15 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie)
reg |= (IS_RC_MSK << IS_RC_SHIFT);
advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+ /*
+ * Replace incorrect PCI vendor id value 0x1b4b by correct value 0x11ab.
+ * VENDOR_ID_REG contains vendor id in low 16 bits and subsystem vendor
+ * id in high 16 bits. Updating this register changes readback value of
+ * read-only vendor id bits in PCIE_CORE_DEV_ID_REG register. Workaround
+ * for erratum 4.1: "The value of device and vendor ID is incorrect".
+ */
+ advk_writel(pcie, 0x11ab11ab, VENDOR_ID_REG);
+
/* Set Advanced Error Capabilities and Control PF0 register */
reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
@@ -534,6 +548,10 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie)
/* Set PCIe Device Control and Status 1 PF0 register */
reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
+ (PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE <<
+ PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE_SHIFT) |
+ (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE <<
+ PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT) |
PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE;
advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
diff --git a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c
index ab6ff45a51..574cb784a8 100644
--- a/drivers/pci/pci_mpc85xx.c
+++ b/drivers/pci/pci_mpc85xx.c
@@ -46,6 +46,7 @@ static int mpc85xx_pci_dm_write_config(struct udevice *dev, pci_dev_t bdf,
return 0;
}
+#ifdef CONFIG_FSL_LAW
static int
mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem,
struct pci_region *pre)
@@ -68,6 +69,7 @@ mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem,
return 0;
}
+#endif
static int mpc85xx_pci_dm_probe(struct udevice *dev)
{
@@ -85,22 +87,24 @@ static int mpc85xx_pci_dm_probe(struct udevice *dev)
return -EINVAL;
}
+#ifdef CONFIG_FSL_LAW
mpc85xx_pci_dm_setup_laws(io, mem, pre);
+#endif
pcix = priv->cfg_addr;
/* BAR 1: memory */
- out_be32(&pcix->potar1, (mem->bus_start >> 12) & 0x000fffff);
- out_be32(&pcix->potear1, 0);
- out_be32(&pcix->powbar1, (mem->phys_start >> 12) & 0x000fffff);
- out_be32(&pcix->powbear1, 0);
+ out_be32(&pcix->potar1, mem->bus_start >> 12);
+ out_be32(&pcix->potear1, (u64)mem->bus_start >> 44);
+ out_be32(&pcix->powbar1, mem->phys_start >> 12);
+ out_be32(&pcix->powbear1, (u64)mem->phys_start >> 44);
out_be32(&pcix->powar1, (POWAR_EN | POWAR_MEM_READ |
POWAR_MEM_WRITE | (__ilog2(mem->size) - 1)));
/* BAR 1: IO */
- out_be32(&pcix->potar2, (io->bus_start >> 12) & 0x000fffff);
- out_be32(&pcix->potear2, 0);
- out_be32(&pcix->powbar2, (io->phys_start >> 12) & 0x000fffff);
- out_be32(&pcix->powbear2, 0);
+ out_be32(&pcix->potar2, io->bus_start >> 12);
+ out_be32(&pcix->potear2, (u64)io->bus_start >> 44);
+ out_be32(&pcix->powbar2, io->phys_start >> 12);
+ out_be32(&pcix->powbear2, (u64)io->phys_start >> 44);
out_be32(&pcix->powar2, (POWAR_EN | POWAR_IO_READ |
POWAR_IO_WRITE | (__ilog2(io->size) - 1)));
@@ -130,9 +134,8 @@ static int mpc85xx_pci_of_to_plat(struct udevice *dev)
addr = devfdt_get_addr_index(dev, 0);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
- priv->cfg_addr = (void __iomem *)addr;
- addr += 4;
- priv->cfg_data = (void __iomem *)addr;
+ priv->cfg_addr = (void __iomem *)map_physmem(addr, 0, MAP_NOCACHE);
+ priv->cfg_data = (void __iomem *)((ulong)priv->cfg_addr + 4);
return 0;
}
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index 235d9bb90c..0c1d7cd770 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -79,7 +79,8 @@ struct mvebu_pcie {
u32 lane;
int devfn;
u32 lane_mask;
- pci_dev_t dev;
+ int first_busno;
+ int local_dev;
char name[16];
unsigned int mem_target;
unsigned int mem_attr;
@@ -144,38 +145,47 @@ static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
return container_of(hose, struct mvebu_pcie, hose);
}
+static int mvebu_pcie_valid_addr(struct mvebu_pcie *pcie, pci_dev_t bdf)
+{
+ /*
+ * There are two devices visible on local bus:
+ * * on slot configured by function mvebu_pcie_set_local_dev_nr()
+ * (by default this register is set to 0) there is a
+ * "Marvell Memory controller", which isn't useful in root complex
+ * mode,
+ * * on all other slots the real PCIe card connected to the PCIe slot.
+ *
+ * We therefore allow access only to the real PCIe card.
+ */
+ if (PCI_BUS(bdf) == pcie->first_busno &&
+ PCI_DEV(bdf) != !pcie->local_dev)
+ return 0;
+
+ return 1;
+}
+
static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct mvebu_pcie *pcie = dev_get_plat(bus);
- int local_bus = PCI_BUS(pcie->dev);
- int local_dev = PCI_DEV(pcie->dev);
- u32 reg;
u32 data;
- debug("PCIE CFG read: loc_bus=%d loc_dev=%d (b,d,f)=(%2d,%2d,%2d) ",
- local_bus, local_dev, PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+ debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
+ PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
- /* Don't access the local host controller via this API */
- if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) == local_dev) {
- debug("- skipping host controller\n");
- *valuep = pci_get_ff(size);
- return 0;
- }
-
- /* If local dev is 0, the first other dev can only be 1 */
- if (PCI_BUS(bdf) == local_bus && local_dev == 0 && PCI_DEV(bdf) != 1) {
+ if (!mvebu_pcie_valid_addr(pcie, bdf)) {
debug("- out of range\n");
*valuep = pci_get_ff(size);
return 0;
}
/* write address */
- reg = PCIE_CONF_ADDR(bdf, offset);
- writel(reg, pcie->base + PCIE_CONF_ADDR_OFF);
+ writel(PCIE_CONF_ADDR(bdf, offset), pcie->base + PCIE_CONF_ADDR_OFF);
+
+ /* read data */
data = readl(pcie->base + PCIE_CONF_DATA_OFF);
- debug("(addr,val)=(0x%04x, 0x%08x)\n", offset, data);
+ debug("(addr,size,val)=(0x%04x, %d, 0x%08x)\n", offset, size, data);
*valuep = pci_conv_32_to_size(data, offset, size);
return 0;
@@ -186,27 +196,21 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
enum pci_size_t size)
{
struct mvebu_pcie *pcie = dev_get_plat(bus);
- int local_bus = PCI_BUS(pcie->dev);
- int local_dev = PCI_DEV(pcie->dev);
u32 data;
- debug("PCIE CFG write: loc_bus=%d loc_dev=%d (b,d,f)=(%2d,%2d,%2d) ",
- local_bus, local_dev, PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
- debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
-
- /* Don't access the local host controller via this API */
- if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) == local_dev) {
- debug("- skipping host controller\n");
- return 0;
- }
+ debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
+ PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+ debug("(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value);
- /* If local dev is 0, the first other dev can only be 1 */
- if (PCI_BUS(bdf) == local_bus && local_dev == 0 && PCI_DEV(bdf) != 1) {
+ if (!mvebu_pcie_valid_addr(pcie, bdf)) {
debug("- out of range\n");
return 0;
}
+ /* write address */
writel(PCIE_CONF_ADDR(bdf, offset), pcie->base + PCIE_CONF_ADDR_OFF);
+
+ /* write data */
data = pci_conv_size_to_32(0, value, offset, size);
writel(data, pcie->base + PCIE_CONF_DATA_OFF);
@@ -273,7 +277,7 @@ static int mvebu_pcie_probe(struct udevice *dev)
struct mvebu_pcie *pcie = dev_get_plat(dev);
struct udevice *ctlr = pci_get_controller(dev);
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
- static int bus;
+ int bus = dev_seq(dev);
u32 reg;
debug("%s: PCIe %d.%d - up, base %08x\n", __func__,
@@ -284,9 +288,11 @@ static int mvebu_pcie_probe(struct udevice *dev)
readl(pcie->base), mvebu_pcie_get_local_bus_nr(pcie),
mvebu_pcie_get_local_dev_nr(pcie));
+ pcie->first_busno = bus;
+ pcie->local_dev = 1;
+
mvebu_pcie_set_local_bus_nr(pcie, bus);
- mvebu_pcie_set_local_dev_nr(pcie, 0);
- pcie->dev = PCI_BDF(bus, 0, 0);
+ mvebu_pcie_set_local_dev_nr(pcie, pcie->local_dev);
pcie->mem.start = (u32)mvebu_pcie_membase;
pcie->mem.end = pcie->mem.start + PCIE_MEM_SIZE - 1;
@@ -336,8 +342,6 @@ static int mvebu_pcie_probe(struct udevice *dev)
writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
- bus++;
-
return 0;
}
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 2b2a6ddb56..7b4c0f02c6 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -31,8 +31,6 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o
obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o
-obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o
-obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o
obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o
obj-$(CONFIG_POWER_PCA9450) += pmic_pca9450.o
obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o
diff --git a/drivers/power/pmic/pmic_max8997.c b/drivers/power/pmic/pmic_max8997.c
deleted file mode 100644
index 1d834ff713..0000000000
--- a/drivers/power/pmic/pmic_max8997.c
+++ /dev/null
@@ -1,107 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2012 Samsung Electronics
- * Lukasz Majewski <l.majewski@samsung.com>
- */
-
-#include <common.h>
-#include <log.h>
-#include <power/pmic.h>
-#include <power/max8997_pmic.h>
-#include <i2c.h>
-#include <errno.h>
-
-unsigned char max8997_reg_ldo(int uV)
-{
- unsigned char ret;
- if (uV <= 800000)
- return 0;
- if (uV >= 3950000)
- return MAX8997_LDO_MAX_VAL;
- ret = (uV - 800000) / 50000;
- if (ret > MAX8997_LDO_MAX_VAL) {
- printf("MAX8997 LDO SETTING ERROR (%duV) -> %u\n", uV, ret);
- ret = MAX8997_LDO_MAX_VAL;
- }
-
- return ret;
-}
-
-static int pmic_charger_state(struct pmic *p, int state, int current)
-{
- unsigned char fc;
- u32 val = 0;
-
- if (pmic_probe(p))
- return -ENODEV;
-
- if (state == PMIC_CHARGER_DISABLE) {
- puts("Disable the charger.\n");
- pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
- val &= ~(MBCHOSTEN | VCHGR_FC);
- pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val);
-
- return -ENOTSUPP;
- }
-
- if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) {
- printf("%s: Wrong charge current: %d [mA]\n",
- __func__, current);
- return -EINVAL;
- }
-
- fc = (current - CHARGER_MIN_CURRENT) / CHARGER_CURRENT_RESOLUTION;
- fc = fc & 0xf; /* up to 950 mA */
-
- printf("Enable the charger @ %d [mA]\n", fc * CHARGER_CURRENT_RESOLUTION
- + CHARGER_MIN_CURRENT);
-
- val = fc | MBCICHFCSET;
- pmic_reg_write(p, MAX8997_REG_MBCCTRL4, val);
-
- pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
- val = MBCHOSTEN | VCHGR_FC; /* enable charger & fast charge */
- pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val);
-
- return 0;
-}
-
-static int pmic_charger_bat_present(struct pmic *p)
-{
- u32 val;
-
- if (pmic_probe(p))
- return -ENODEV;
-
- pmic_reg_read(p, MAX8997_REG_STATUS4, &val);
-
- return !(val & DETBAT);
-}
-
-static struct power_chrg power_chrg_pmic_ops = {
- .chrg_bat_present = pmic_charger_bat_present,
- .chrg_state = pmic_charger_state,
-};
-
-int pmic_init(unsigned char bus)
-{
- static const char name[] = "MAX8997_PMIC";
- struct pmic *p = pmic_alloc();
-
- if (!p) {
- printf("%s: POWER allocation error!\n", __func__);
- return -ENOMEM;
- }
-
- debug("Board PMIC init\n");
-
- p->name = name;
- p->interface = PMIC_I2C;
- p->number_of_regs = PMIC_NUM_OF_REGS;
- p->hw.i2c.addr = MAX8997_I2C_ADDR;
- p->hw.i2c.tx_num = 1;
- p->bus = bus;
-
- p->chrg = &power_chrg_pmic_ops;
- return 0;
-}
diff --git a/drivers/power/pmic/pmic_max8998.c b/drivers/power/pmic/pmic_max8998.c
deleted file mode 100644
index f058238c92..0000000000
--- a/drivers/power/pmic/pmic_max8998.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2011 Samsung Electronics
- * Lukasz Majewski <l.majewski@samsung.com>
- */
-
-#include <common.h>
-#include <power/pmic.h>
-#include <power/max8998_pmic.h>
-#include <errno.h>
-
-int pmic_init(unsigned char bus)
-{
- static const char name[] = "MAX8998_PMIC";
- struct pmic *p = pmic_alloc();
-
- if (!p) {
- printf("%s: POWER allocation error!\n", __func__);
- return -ENOMEM;
- }
-
- puts("Board PMIC init\n");
-
- p->name = name;
- p->interface = PMIC_I2C;
- p->number_of_regs = PMIC_NUM_OF_REGS;
- p->hw.i2c.addr = MAX8998_I2C_ADDR;
- p->hw.i2c.tx_num = 1;
- p->bus = bus;
-
- return 0;
-}
diff --git a/drivers/rng/iproc_rng200.c b/drivers/rng/iproc_rng200.c
index f71f285f53..85ac15bf9c 100644
--- a/drivers/rng/iproc_rng200.c
+++ b/drivers/rng/iproc_rng200.c
@@ -33,13 +33,13 @@
#define RNG_FIFO_COUNT_OFFSET 0x24
#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x000000FF
-struct iproc_rng200_platdata {
- fdt_addr_t base;
+struct iproc_rng200_plat {
+ void __iomem *base;
};
-static void iproc_rng200_enable(struct iproc_rng200_platdata *pdata, bool enable)
+static void iproc_rng200_enable(struct iproc_rng200_plat *pdata, bool enable)
{
- fdt_addr_t rng_base = pdata->base;
+ void __iomem *rng_base = pdata->base;
u32 val;
val = readl(rng_base + RNG_CTRL_OFFSET);
@@ -52,9 +52,9 @@ static void iproc_rng200_enable(struct iproc_rng200_platdata *pdata, bool enable
writel(val, rng_base + RNG_CTRL_OFFSET);
}
-static void iproc_rng200_restart(struct iproc_rng200_platdata *pdata)
+static void iproc_rng200_restart(struct iproc_rng200_plat *pdata)
{
- fdt_addr_t rng_base = pdata->base;
+ void __iomem *rng_base = pdata->base;
u32 val;
iproc_rng200_enable(pdata, false);
@@ -84,7 +84,7 @@ static void iproc_rng200_restart(struct iproc_rng200_platdata *pdata)
static int iproc_rng200_read(struct udevice *dev, void *data, size_t len)
{
- struct iproc_rng200_platdata *priv = dev_get_plat(dev);
+ struct iproc_rng200_plat *priv = dev_get_plat(dev);
char *buf = (char *)data;
u32 num_remaining = len;
u32 status;
@@ -136,7 +136,7 @@ static int iproc_rng200_read(struct udevice *dev, void *data, size_t len)
static int iproc_rng200_probe(struct udevice *dev)
{
- struct iproc_rng200_platdata *priv = dev_get_plat(dev);
+ struct iproc_rng200_plat *priv = dev_get_plat(dev);
iproc_rng200_enable(priv, true);
@@ -145,18 +145,18 @@ static int iproc_rng200_probe(struct udevice *dev)
static int iproc_rng200_remove(struct udevice *dev)
{
- struct iproc_rng200_platdata *priv = dev_get_plat(dev);
+ struct iproc_rng200_plat *priv = dev_get_plat(dev);
iproc_rng200_enable(priv, false);
return 0;
}
-static int iproc_rng200_ofdata_to_platdata(struct udevice *dev)
+static int iproc_rng200_of_to_plat(struct udevice *dev)
{
- struct iproc_rng200_platdata *pdata = dev_get_plat(dev);
+ struct iproc_rng200_plat *pdata = dev_get_plat(dev);
- pdata->base = dev_read_addr(dev);
+ pdata->base = devfdt_map_physmem(dev, sizeof(void *));
if (!pdata->base)
return -ENODEV;
@@ -180,6 +180,6 @@ U_BOOT_DRIVER(iproc_rng200_rng) = {
.ops = &iproc_rng200_ops,
.probe = iproc_rng200_probe,
.remove = iproc_rng200_remove,
- .plat_auto = sizeof(struct iproc_rng200_platdata),
- .of_to_plat = iproc_rng200_ofdata_to_platdata,
+ .priv_auto = sizeof(struct iproc_rng200_plat),
+ .of_to_plat = iproc_rng200_of_to_plat,
};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 79ad0a1b34..24413d14f9 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -722,6 +722,13 @@ config ROCKCHIP_SERIAL
This uses the ns16550 driver, converting the platdata from of-platdata
to the ns16550 format.
+config S5P_SERIAL
+ bool "Support for Samsung S5P UART"
+ depends on ARCH_EXYNOS || ARCH_S5PC1XX
+ default y
+ help
+ Select this to enable Samsung S5P UART support.
+
config SANDBOX_SERIAL
bool "Sandbox UART support"
depends on SANDBOX
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 0c3810f5d5..92bcb30b85 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_EFI_APP) += serial_efi.o
obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
obj-$(CONFIG_MCFUART) += serial_mcf.o
obj-$(CONFIG_SYS_NS16550) += ns16550.o
-obj-$(CONFIG_S5P) += serial_s5p.o
+obj-$(CONFIG_S5P_SERIAL) += serial_s5p.o
obj-$(CONFIG_MXC_UART) += serial_mxc.o
obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
obj-$(CONFIG_MESON_SERIAL) += serial_meson.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index b9e99babeb..cc121eee27 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -483,7 +483,7 @@ static int ns16550_serial_getinfo(struct udevice *dev,
return 0;
}
-static int ns16550_serial_assign_base(struct ns16550_plat *plat, ulong base)
+static int ns16550_serial_assign_base(struct ns16550_plat *plat, fdt_addr_t base)
{
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -564,6 +564,8 @@ int ns16550_serial_of_to_plat(struct udevice *dev)
if (!plat->clock)
plat->clock = dev_read_u32_default(dev, "clock-frequency",
CONFIG_SYS_NS16550_CLK);
+ if (!plat->clock)
+ plat->clock = CONFIG_SYS_NS16550_CLK;
if (!plat->clock) {
debug("ns16550 clock not defined\n");
return -EINVAL;
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 2883e2466f..799d524047 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -127,7 +127,7 @@ static int zynq_serial_setbrg(struct udevice *dev, int baudrate)
debug("%s: CLK %ld\n", __func__, clock);
ret = clk_enable(&clk);
- if (ret && ret != -ENOSYS) {
+ if (ret) {
dev_err(dev, "failed to enable clock\n");
return ret;
}
diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c
index f1c1a260da..4f4eb02de0 100644
--- a/drivers/serial/usbtty.c
+++ b/drivers/serial/usbtty.c
@@ -500,8 +500,8 @@ void usbtty_puts(struct stdio_dev *dev, const char *str)
n = next_nl_pos (str);
if (str[n] == '\n') {
- __usbtty_puts("\r", 1);
- __usbtty_puts(str, n + 1);
+ __usbtty_puts(str, n);
+ __usbtty_puts("\r\n", 2);
str += (n + 1);
len -= (n + 1);
} else {
@@ -849,17 +849,9 @@ static int write_buffer (circbuf_t * buf)
&endpoint_instance[tx_endpoint];
struct urb *current_urb = NULL;
- current_urb = next_urb (device_instance, endpoint);
-
- if (!current_urb) {
- TTYERR ("current_urb is NULL, buf->size %d\n",
- buf->size);
- return 0;
- }
-
/* TX data still exists - send it now
*/
- if(endpoint->sent < current_urb->actual_length){
+ if(endpoint->sent < endpoint->tx_urb->actual_length){
if(udc_endpoint_write (endpoint)){
/* Write pre-empted by RX */
return -1;
@@ -878,6 +870,8 @@ static int write_buffer (circbuf_t * buf)
*/
while (buf->size > 0) {
+ current_urb = next_urb (device_instance, endpoint);
+
dest = (char*)current_urb->buffer +
current_urb->actual_length;
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
index bb68eb90e9..f3dddbdbd7 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/mxc_spi.c
@@ -662,7 +662,10 @@ static int mxc_spi_release_bus(struct udevice *dev)
static int mxc_spi_set_speed(struct udevice *bus, uint speed)
{
- /* Nothing to do */
+ struct mxc_spi_slave *mxcs = dev_get_plat(bus);
+
+ mxcs->max_hz = speed;
+
return 0;
}
diff --git a/drivers/spi/nxp_fspi.c b/drivers/spi/nxp_fspi.c
index 012f304595..6c5bad4c2c 100644
--- a/drivers/spi/nxp_fspi.c
+++ b/drivers/spi/nxp_fspi.c
@@ -823,7 +823,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
/* the default frequency, we will change it later if necessary. */
ret = clk_set_rate(&f->clk, 20000000);
- if (ret)
+ if (ret < 0)
return ret;
ret = nxp_fspi_clk_prep_enable(f);
@@ -914,7 +914,7 @@ static int nxp_fspi_set_speed(struct udevice *bus, uint speed)
nxp_fspi_clk_disable_unprep(f);
ret = clk_set_rate(&f->clk, speed);
- if (ret)
+ if (ret < 0)
return ret;
ret = nxp_fspi_clk_prep_enable(f);
diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 75e5e840ed..4acc9047b9 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -16,6 +16,7 @@
#include <reset.h>
#include <spi.h>
#include <spi-mem.h>
+#include <watchdog.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
@@ -171,6 +172,7 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv,
static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr)
{
*val = readb(addr);
+ WATCHDOG_RESET();
}
static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr)
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index 3d829bcb73..cf6da5340a 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -194,7 +194,7 @@ static int zynq_qspi_probe(struct udevice *bus)
}
ret = clk_enable(&clk);
- if (ret && ret != -ENOSYS) {
+ if (ret) {
dev_err(bus, "failed to enable clock\n");
return ret;
}
diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
index 52b8fbc874..b3e0858eb9 100644
--- a/drivers/spi/zynq_spi.c
+++ b/drivers/spi/zynq_spi.c
@@ -144,7 +144,7 @@ static int zynq_spi_probe(struct udevice *bus)
}
ret = clk_enable(&clk);
- if (ret && ret != -ENOSYS) {
+ if (ret) {
dev_err(bus, "failed to enable clock\n");
return ret;
}
diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index f669974af1..f8d13d193e 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -17,6 +17,7 @@
#include <malloc.h>
#include <memalign.h>
#include <spi.h>
+#include <spi-mem.h>
#include <ubi_uboot.h>
#include <wait_bit.h>
#include <dm/device_compat.h>
@@ -172,8 +173,7 @@ struct zynqmp_qspi_priv {
unsigned int len;
int bytes_to_transfer;
int bytes_to_receive;
- unsigned int is_inst;
- unsigned int cs_change:1;
+ const struct spi_mem_op *op;
};
static int zynqmp_qspi_of_to_plat(struct udevice *bus)
@@ -222,6 +222,21 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv *priv)
return gqspi_fifo_reg;
}
+static u32 zynqmp_qspi_genfifo_mode(u8 buswidth)
+{
+ switch (buswidth) {
+ case 1:
+ return GQSPI_SPI_MODE_SPI;
+ case 2:
+ return GQSPI_SPI_MODE_DUAL_SPI;
+ case 4:
+ return GQSPI_SPI_MODE_QSPI;
+ default:
+ debug("Unsupported bus width %u\n", buswidth);
+ return GQSPI_SPI_MODE_SPI;
+ }
+}
+
static void zynqmp_qspi_fill_gen_fifo(struct zynqmp_qspi_priv *priv,
u32 gqspi_fifo_reg)
{
@@ -306,12 +321,9 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, uint speed)
if (speed > plat->frequency)
speed = plat->frequency;
- /* Set the clock frequency */
- confr = readl(&regs->confr);
- if (speed == 0) {
- /* Set baudrate x8, if the freq is 0 */
- baud_rate_val = GQSPI_DFLT_BAUD_RATE_VAL;
- } else if (plat->speed_hz != speed) {
+ if (plat->speed_hz != speed) {
+ /* Set the clock frequency */
+ /* If speed == 0, default to lowest speed */
while ((baud_rate_val < 8) &&
((plat->frequency /
(2 << baud_rate_val)) > speed))
@@ -321,13 +333,15 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, uint speed)
baud_rate_val = GQSPI_DFLT_BAUD_RATE_VAL;
plat->speed_hz = plat->frequency / (2 << baud_rate_val);
- }
- confr &= ~GQSPI_BAUD_DIV_MASK;
- confr |= (baud_rate_val << 3);
- writel(confr, &regs->confr);
- zynqmp_qspi_set_tapdelay(bus, baud_rate_val);
- debug("regs=%p, speed=%d\n", priv->regs, plat->speed_hz);
+ confr = readl(&regs->confr);
+ confr &= ~GQSPI_BAUD_DIV_MASK;
+ confr |= (baud_rate_val << 3);
+ writel(confr, &regs->confr);
+ zynqmp_qspi_set_tapdelay(bus, baud_rate_val);
+
+ debug("regs=%p, speed=%d\n", priv->regs, plat->speed_hz);
+ }
return 0;
}
@@ -359,7 +373,7 @@ static int zynqmp_qspi_probe(struct udevice *bus)
debug("%s: CLK %ld\n", __func__, clock);
ret = clk_enable(&clk);
- if (ret && ret != -ENOSYS) {
+ if (ret) {
dev_err(bus, "failed to enable clock\n");
return ret;
}
@@ -446,21 +460,42 @@ static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size)
static void zynqmp_qspi_genfifo_cmd(struct zynqmp_qspi_priv *priv)
{
+ const struct spi_mem_op *op = priv->op;
u32 gen_fifo_cmd;
- u32 bytecount = 0;
+ u8 i, dummy_cycles, addr;
+
+ /* Send opcode */
+ gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+ gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(op->cmd.buswidth);
+ gen_fifo_cmd |= GQSPI_GFIFO_TX;
+ gen_fifo_cmd |= op->cmd.opcode;
+ zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
+
+ /* Send address */
+ for (i = 0; i < op->addr.nbytes; i++) {
+ addr = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
- while (priv->len) {
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
- gen_fifo_cmd |= GQSPI_GFIFO_TX | GQSPI_SPI_MODE_SPI;
- gen_fifo_cmd |= *(u8 *)priv->tx_buf;
- bytecount++;
- priv->len--;
- priv->tx_buf = (u8 *)priv->tx_buf + 1;
+ gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(op->addr.buswidth);
+ gen_fifo_cmd |= GQSPI_GFIFO_TX;
+ gen_fifo_cmd |= addr;
debug("GFIFO_CMD_Cmd = 0x%x\n", gen_fifo_cmd);
zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
}
+
+ /* Send dummy */
+ if (op->dummy.nbytes) {
+ dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth;
+
+ gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+ gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(op->dummy.buswidth);
+ gen_fifo_cmd &= ~(GQSPI_GFIFO_TX | GQSPI_GFIFO_RX);
+ gen_fifo_cmd |= GQSPI_GFIFO_DATA_XFR_MASK;
+ gen_fifo_cmd |= dummy_cycles;
+ zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
+ }
}
static u32 zynqmp_qspi_calc_exp(struct zynqmp_qspi_priv *priv,
@@ -497,11 +532,10 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
int ret = 0;
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+ gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
gen_fifo_cmd |= GQSPI_GFIFO_TX |
GQSPI_GFIFO_DATA_XFR_MASK;
- gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
-
while (priv->len) {
len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
@@ -575,11 +609,10 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv)
u32 actuallen = priv->len;
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+ gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
gen_fifo_cmd |= GQSPI_GFIFO_RX |
GQSPI_GFIFO_DATA_XFR_MASK;
- gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
-
/*
* Check if receive buffer is aligned to 4 byte and length
* is multiples of four byte as we are using dma to receive.
@@ -596,62 +629,6 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv)
return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
}
-static int zynqmp_qspi_start_transfer(struct zynqmp_qspi_priv *priv)
-{
- int ret = 0;
-
- if (priv->is_inst) {
- if (priv->tx_buf)
- zynqmp_qspi_genfifo_cmd(priv);
- else
- return -EINVAL;
- } else {
- if (priv->tx_buf)
- ret = zynqmp_qspi_genfifo_fill_tx(priv);
- else if (priv->rx_buf)
- ret = zynqmp_qspi_genfifo_fill_rx(priv);
- else
- return -EINVAL;
- }
- return ret;
-}
-
-static int zynqmp_qspi_transfer(struct zynqmp_qspi_priv *priv)
-{
- static unsigned int cs_change = 1;
- int status = 0;
-
- debug("%s\n", __func__);
-
- while (1) {
- /* Select the chip if required */
- if (cs_change)
- zynqmp_qspi_chipselect(priv, 1);
-
- cs_change = priv->cs_change;
-
- if (!priv->tx_buf && !priv->rx_buf && priv->len) {
- status = -EINVAL;
- break;
- }
-
- /* Request the transfer */
- if (priv->len) {
- status = zynqmp_qspi_start_transfer(priv);
- priv->is_inst = 0;
- if (status < 0)
- break;
- }
-
- if (cs_change)
- /* Deselect the chip */
- zynqmp_qspi_chipselect(priv, 0);
- break;
- }
-
- return status;
-}
-
static int zynqmp_qspi_claim_bus(struct udevice *dev)
{
struct udevice *bus = dev->parent;
@@ -674,45 +651,43 @@ static int zynqmp_qspi_release_bus(struct udevice *dev)
return 0;
}
-int zynqmp_qspi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout,
- void *din, unsigned long flags)
+static int zynqmp_qspi_exec_op(struct spi_slave *slave,
+ const struct spi_mem_op *op)
{
- struct udevice *bus = dev->parent;
- struct zynqmp_qspi_priv *priv = dev_get_priv(bus);
+ struct zynqmp_qspi_priv *priv = dev_get_priv(slave->dev->parent);
+ int ret = 0;
- debug("%s: priv: 0x%08lx bitlen: %d dout: 0x%08lx ", __func__,
- (unsigned long)priv, bitlen, (unsigned long)dout);
- debug("din: 0x%08lx flags: 0x%lx\n", (unsigned long)din, flags);
+ priv->op = op;
+ priv->tx_buf = op->data.buf.out;
+ priv->rx_buf = op->data.buf.in;
+ priv->len = op->data.nbytes;
- priv->tx_buf = dout;
- priv->rx_buf = din;
- priv->len = bitlen / 8;
+ zynqmp_qspi_chipselect(priv, 1);
- /*
- * Assume that the beginning of a transfer with bits to
- * transmit must contain a device command.
- */
- if (dout && flags & SPI_XFER_BEGIN)
- priv->is_inst = 1;
- else
- priv->is_inst = 0;
+ /* Send opcode, addr, dummy */
+ zynqmp_qspi_genfifo_cmd(priv);
- if (flags & SPI_XFER_END)
- priv->cs_change = 1;
- else
- priv->cs_change = 0;
+ /* Request the transfer */
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ ret = zynqmp_qspi_genfifo_fill_rx(priv);
+ else if (op->data.dir == SPI_MEM_DATA_OUT)
+ ret = zynqmp_qspi_genfifo_fill_tx(priv);
- zynqmp_qspi_transfer(priv);
+ zynqmp_qspi_chipselect(priv, 0);
- return 0;
+ return ret;
}
+static const struct spi_controller_mem_ops zynqmp_qspi_mem_ops = {
+ .exec_op = zynqmp_qspi_exec_op,
+};
+
static const struct dm_spi_ops zynqmp_qspi_ops = {
.claim_bus = zynqmp_qspi_claim_bus,
.release_bus = zynqmp_qspi_release_bus,
- .xfer = zynqmp_qspi_xfer,
.set_speed = zynqmp_qspi_set_speed,
.set_mode = zynqmp_qspi_set_mode,
+ .mem_ops = &zynqmp_qspi_mem_ops,
};
static const struct udevice_id zynqmp_qspi_ids[] = {
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 0e5c7c9971..ac77ffbc8b 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -33,6 +33,12 @@ config TPL_SYSRESET
if SYSRESET
+config SYSRESET_CMD_RESET
+ bool "sysreset implementation of the reset command"
+ default y
+ help
+ Enable sysreset implementation of the reset command.
+
if CMD_POWEROFF
config SYSRESET_CMD_POWEROFF
@@ -88,7 +94,7 @@ config SYSRESET_SOCFPGA
config SYSRESET_SOCFPGA_SOC64
bool "Enable support for Intel SOCFPGA SoC64 family (Stratix10/Agilex)"
- depends on ARCH_SOCFPGA && (TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX)
+ depends on ARCH_SOCFPGA && TARGET_SOCFPGA_SOC64
help
This enables the system reset driver support for Intel SOCFPGA
SoC64 SoCs.
diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c
index a9908ebf79..6c9dc7a384 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -119,6 +119,7 @@ void reset_cpu(ulong addr)
}
+#if IS_ENABLED(CONFIG_SYSRESET_CMD_RESET)
int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
printf("resetting ...\n");
@@ -128,6 +129,7 @@ int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return 0;
}
+#endif
#if IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c
index 02cefecd0d..07766baf45 100644
--- a/drivers/thermal/imx_tmu.c
+++ b/drivers/thermal/imx_tmu.c
@@ -344,6 +344,7 @@ static int imx_tmu_bind(struct udevice *dev)
ofnode node, offset;
const char *name;
const void *prop;
+ int minc, maxc;
debug("%s dev name %s\n", __func__, dev->name);
@@ -352,6 +353,10 @@ static int imx_tmu_bind(struct udevice *dev)
return 0;
pdata->zone_node = 1;
+ /* default alert/crit temps based on temp grade */
+ get_cpu_temp_grade(&minc, &maxc);
+ pdata->critical = maxc * 1000;
+ pdata->alert = (maxc - 10) * 1000;
node = ofnode_path("/thermal-zones");
ofnode_for_each_subnode(offset, node) {
@@ -443,6 +448,7 @@ static int imx_tmu_probe(struct udevice *dev)
if (pdata->zone_node) {
imx_tmu_init(dev);
imx_tmu_calibration(dev);
+ imx_tmu_enable_msite(dev);
} else {
imx_tmu_enable_msite(dev);
}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 6e291198ab..f6975730bf 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -95,6 +95,7 @@ config USB_STORAGE
config USB_KEYBOARD
bool "USB Keyboard support"
+ select DM_KEYBOARD if DM_USB
select SYS_STDIO_DEREGISTER
---help---
Say Y here if you want to use a USB keyboard for U-Boot command line
diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
index ecac80fc11..2f31814442 100644
--- a/drivers/usb/gadget/dwc2_udc_otg.c
+++ b/drivers/usb/gadget/dwc2_udc_otg.c
@@ -248,9 +248,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
debug_cond(DEBUG_SETUP != 0, "%s: %s\n", __func__, "no name");
- if (!driver
- || (driver->speed != USB_SPEED_FULL
- && driver->speed != USB_SPEED_HIGH)
+ if (!driver || driver->speed < USB_SPEED_FULL
|| !driver->bind || !driver->disconnect || !driver->setup)
return -EINVAL;
if (!dev)
@@ -320,9 +318,7 @@ static int dwc2_gadget_start(struct usb_gadget *g,
debug_cond(DEBUG_SETUP != 0, "%s: %s\n", __func__, "no name");
- if (!driver ||
- (driver->speed != USB_SPEED_FULL &&
- driver->speed != USB_SPEED_HIGH) ||
+ if (!driver || driver->speed < USB_SPEED_FULL ||
!driver->bind || !driver->disconnect || !driver->setup)
return -EINVAL;
diff --git a/drivers/usb/gadget/ep0.c b/drivers/usb/gadget/ep0.c
index 457679f0a4..6624f61b76 100644
--- a/drivers/usb/gadget/ep0.c
+++ b/drivers/usb/gadget/ep0.c
@@ -294,7 +294,7 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
{
struct usb_string_descriptor *string_descriptor;
if (!(string_descriptor = usbd_get_string (index))) {
- serial_printf("Invalid string index %d\n", index);
+ dbg_ep0(0, "Invalid string index %d\n", index);
return -1;
}
dbg_ep0(3, "string_descriptor: %p length %d", string_descriptor, string_descriptor->bLength);
@@ -302,14 +302,14 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
}
break;
case USB_DESCRIPTOR_TYPE_INTERFACE:
- serial_printf("USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
+ dbg_ep0(2, "USB_DESCRIPTOR_TYPE_INTERFACE - error not implemented\n");
return -1;
case USB_DESCRIPTOR_TYPE_ENDPOINT:
- serial_printf("USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
+ dbg_ep0(2, "USB_DESCRIPTOR_TYPE_ENDPOINT - error not implemented\n");
return -1;
case USB_DESCRIPTOR_TYPE_HID:
{
- serial_printf("USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
+ dbg_ep0(2, "USB_DESCRIPTOR_TYPE_HID - error not implemented\n");
return -1; /* unsupported at this time */
#if 0
int bNumInterface =
@@ -338,7 +338,7 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
break;
case USB_DESCRIPTOR_TYPE_REPORT:
{
- serial_printf("USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
+ dbg_ep0(2, "USB_DESCRIPTOR_TYPE_REPORT - error not implemented\n");
return -1; /* unsupported at this time */
#if 0
int bNumInterface =
@@ -531,7 +531,7 @@ int ep0_recv_setup (struct urb *urb)
le16_to_cpu (request->wValue) & 0xff);
case USB_REQ_GET_CONFIGURATION:
- serial_printf("get config %d\n", device->configuration);
+ dbg_ep0(2, "get config %d\n", device->configuration);
return ep0_get_one (device, urb,
device->configuration);
@@ -621,14 +621,14 @@ int ep0_recv_setup (struct urb *urb)
device->interface = device->alternate = 0;
/*dbg_ep0(2, "set configuration: %d", device->configuration); */
- /*serial_printf("DEVICE_CONFIGURED.. event?\n"); */
+ /*dbg_ep0(2, "DEVICE_CONFIGURED.. event?\n"); */
return 0;
case USB_REQ_SET_INTERFACE:
device->interface = le16_to_cpu (request->wIndex);
device->alternate = le16_to_cpu (request->wValue);
/*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
- serial_printf("DEVICE_SET_INTERFACE.. event?\n");
+ dbg_ep0(2, "DEVICE_SET_INTERFACE.. event?\n");
return 0;
case USB_REQ_GET_STATUS:
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 950cc11949..8ba55aab9f 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -494,6 +494,18 @@ static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
do_exit_on_complete(ep, req);
}
+#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req)
+{
+ /* When usb dequeue complete will be called
+ * Need status value before call run_command.
+ * otherwise, host can't get last message.
+ */
+ if (req->status == 0)
+ fastboot_acmd_complete();
+}
+#endif
+
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{
char *cmdbuf = req->buf;
@@ -532,6 +544,11 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
case FASTBOOT_COMMAND_REBOOT_RECOVERY:
fastboot_func->in_req->complete = compl_do_reset;
break;
+#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+ case FASTBOOT_COMMAND_ACMD:
+ fastboot_func->in_req->complete = do_acmd_complete;
+ break;
+#endif
}
}
diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c
index 801c2bc416..95eaf6d236 100644
--- a/drivers/usb/mtu3/mtu3_qmu.c
+++ b/drivers/usb/mtu3/mtu3_qmu.c
@@ -198,6 +198,7 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
enq->flag &= ~GPD_FLAGS_HWO;
gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq));
+ mtu3_flush_cache((uintptr_t)enq, sizeof(*gpd));
if (req->zero)
gpd->ext_flag |= GPD_EXT_FLAG_ZLP;
@@ -234,6 +235,8 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
enq->flag &= ~GPD_FLAGS_HWO;
gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq));
+ mtu3_flush_cache((uintptr_t)enq, sizeof(*gpd));
+
gpd->flag |= GPD_FLAGS_IOC | GPD_FLAGS_HWO;
mreq->gpd = gpd;
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 147b2eb929..9651f074a4 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -50,7 +50,7 @@ void musb_start(void)
# define config_fifo(dir, idx, addr) \
do { \
writeb(idx, &musbr->dir##fifosz); \
- writew(fifoaddr >> 3, &musbr->dir##fifoadd); \
+ writew(addr, &musbr->dir##fifoadd); \
} while (0)
#endif
@@ -66,14 +66,14 @@ void musb_start(void)
void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
{
u16 csr;
- u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */
+ u16 fifoaddr = 64 >> 3; /* First 64 bytes of FIFO reserved for EP0 */
u32 fifosize;
u8 idx;
while (cnt--) {
/* prepare fifosize to write to register */
fifosize = epinfo->epsize >> 3;
- idx = ffs(fifosize) - 1;
+ idx = fifosize ? ((ffs(fifosize) - 1) & 0xF) : 0;
writeb(epinfo->epnum, &musbr->index);
if (epinfo->epdir) {
@@ -81,10 +81,8 @@ void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
config_fifo(tx, idx, fifoaddr);
csr = readw(&musbr->txcsr);
-#if defined(CONFIG_USB_MUSB_HCD)
/* clear the data toggle bit */
writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
-#endif
/* Flush fifo if required */
if (csr & MUSB_TXCSR_TXPKTRDY)
writew(csr | MUSB_TXCSR_FLUSHFIFO,
@@ -94,16 +92,14 @@ void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
config_fifo(rx, idx, fifoaddr);
csr = readw(&musbr->rxcsr);
-#if defined(CONFIG_USB_MUSB_HCD)
/* clear the data toggle bit */
writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
-#endif
/* Flush fifo if required */
if (csr & MUSB_RXCSR_RXPKTRDY)
writew(csr | MUSB_RXCSR_FLUSHFIFO,
&musbr->rxcsr);
}
- fifoaddr += epinfo->epsize;
+ fifoaddr += 1 << idx;
epinfo++;
}
}
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
index d901f8777c..b9510e3045 100644
--- a/drivers/usb/musb/musb_udc.c
+++ b/drivers/usb/musb/musb_udc.c
@@ -104,6 +104,8 @@ struct usb_endpoint_instance *ep0_endpoint;
static struct usb_device_instance *udc_device;
static int enabled;
+static u16 pending_intrrx;
+
#ifdef MUSB_DEBUG
static void musb_db_regs(void)
{
@@ -629,7 +631,7 @@ static void musb_peri_ep0(void)
static void musb_peri_rx_ep(unsigned int ep)
{
u16 peri_rxcount;
- u8 peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
+ u16 peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
if (!(peri_rxcsr & MUSB_RXCSR_RXPKTRDY)) {
if (debug_level > 0)
@@ -664,7 +666,10 @@ static void musb_peri_rx_ep(unsigned int ep)
/* The common musb fifo reader */
read_fifo(ep, length, data);
- musb_peri_rx_ack(ep);
+ if (length == peri_rxcount)
+ musb_peri_rx_ack(ep);
+ else
+ pending_intrrx |= (1 << ep);
/*
* urb's actual_length is updated in
@@ -677,18 +682,24 @@ static void musb_peri_rx_ep(unsigned int ep)
serial_printf("ERROR : %s %d no space "
"in rcv buffer\n",
__PRETTY_FUNCTION__, ep);
+
+ pending_intrrx |= (1 << ep);
}
} else {
if (debug_level > 0)
serial_printf("ERROR : %s %d problem with "
"endpoint\n",
__PRETTY_FUNCTION__, ep);
+
+ pending_intrrx |= (1 << ep);
}
} else {
if (debug_level > 0)
serial_printf("ERROR : %s %d with nothing to do\n",
__PRETTY_FUNCTION__, ep);
+
+ musb_peri_rx_ack(ep);
}
}
@@ -696,9 +707,7 @@ static void musb_peri_rx(u16 intr)
{
unsigned int ep;
- /* Check for EP0 */
- if (0x01 & intr)
- musb_peri_ep0();
+ /* First bit is reserved and does not indicate interrupt for EP0 */
for (ep = 1; ep < 16; ep++) {
if ((1 << ep) & intr)
@@ -708,21 +717,16 @@ static void musb_peri_rx(u16 intr)
static void musb_peri_tx(u16 intr)
{
- /* Check for EP0 */
+ unsigned int ep;
+
+ /* Check for EP0: first bit indicates interrupt for both RX and TX */
if (0x01 & intr)
- musb_peri_ep0_tx();
+ musb_peri_ep0();
- /*
- * Use this in the future when handling epN tx
- *
- * u8 ep;
- *
- * for (ep = 1; ep < 16; ep++) {
- * if ((1 << ep) & intr) {
- * / * handle tx for this endpoint * /
- * }
- * }
- */
+ for (ep = 1; ep < 16; ep++) {
+ if ((1 << ep) & intr)
+ udc_endpoint_write(GET_ENDPOINT(udc_device, ep));
+ }
}
void udc_irq(void)
@@ -744,8 +748,6 @@ void udc_irq(void)
musb_peri_resume();
}
- musb_peri_ep0();
-
if (MUSB_INTR_RESET & intrusb) {
usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
musb_peri_reset();
@@ -775,13 +777,16 @@ void udc_irq(void)
intrrx = readw(&musbr->intrrx);
intrtx = readw(&musbr->intrtx);
+ intrrx |= pending_intrrx;
+ pending_intrrx = 0;
+
if (intrrx)
musb_peri_rx(intrrx);
if (intrtx)
musb_peri_tx(intrtx);
} else {
- if (MUSB_INTR_SOF & intrusb) {
+ if (readw(&musbr->intrtx) & 0x1) {
u8 faddr;
faddr = readb(&musbr->faddr);
/*
@@ -870,18 +875,8 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
ep0_endpoint->endpoint_address = 0xff;
ep0_urb = usbd_alloc_urb(device, endpoint);
} else if (MAX_ENDPOINT >= id) {
- int ep_addr;
-
- /* Check the direction */
- ep_addr = endpoint->endpoint_address;
- if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
- /* IN */
- epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
- } else {
- /* OUT */
- epinfo[id * 2].epsize = endpoint->rcv_packetSize;
- }
-
+ epinfo[(id * 2) + 0].epsize = endpoint->rcv_packetSize;
+ epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo));
} else {
if (debug_level > 0)
diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c
index 4dde648814..9ae09eec12 100644
--- a/drivers/video/dw_mipi_dsi.c
+++ b/drivers/video/dw_mipi_dsi.c
@@ -721,15 +721,15 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
val & PHY_LOCK, PHY_STATUS_TIMEOUT_US);
if (ret)
- dev_warn(dsi->dsi_host.dev,
- "failed to wait phy lock state\n");
+ dev_dbg(dsi->dsi_host.dev,
+ "failed to wait phy lock state\n");
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
val, val & PHY_STOP_STATE_CLK_LANE,
PHY_STATUS_TIMEOUT_US);
if (ret)
- dev_warn(dsi->dsi_host.dev,
- "failed to wait phy clk lane stop state\n");
+ dev_dbg(dsi->dsi_host.dev,
+ "failed to wait phy clk lane stop state\n");
}
static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
@@ -797,6 +797,7 @@ static int dw_mipi_dsi_init(struct udevice *dev,
dsi->phy_ops = phy_ops;
dsi->max_data_lanes = max_data_lanes;
dsi->device = device;
+ dsi->dsi_host.dev = (struct device *)dev;
dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
device->host = &dsi->dsi_host;
diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c
index 8891ca4b78..4027e978c8 100644
--- a/drivers/video/stm32/stm32_dsi.c
+++ b/drivers/video/stm32/stm32_dsi.c
@@ -483,6 +483,9 @@ static int stm32_dsi_probe(struct udevice *dev)
if (priv->hw_version != HWVER_130 &&
priv->hw_version != HWVER_131) {
dev_err(dev, "DSI version 0x%x not supported\n", priv->hw_version);
+ dev_dbg(dev, "remove and unbind all DSI child\n");
+ device_chld_remove(dev, NULL, DM_REMOVE_NORMAL);
+ device_chld_unbind(dev, NULL);
ret = -ENODEV;
goto err_clk;
}
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index e800720657..1835607083 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -55,6 +55,7 @@ config VIRTIO_NET
config VIRTIO_BLK
bool "virtio block driver"
depends on VIRTIO
+ depends on BLK
help
This is the virtual block driver for virtio. It can be used with
QEMU based targets.
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index cf2cfaef2c..0379536c54 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -227,7 +227,7 @@ static int virtio_uclass_post_probe(struct udevice *udev)
struct udevice *vdev;
int ret;
- if (uc_priv->device > VIRTIO_ID_MAX_NUM) {
+ if (uc_priv->device >= VIRTIO_ID_MAX_NUM) {
debug("(%s): virtio device ID %d exceeds maximum num\n",
udev->name, uc_priv->device);
return 0;
diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c
index 9137d87697..11b30ae85d 100644
--- a/drivers/watchdog/xilinx_wwdt.c
+++ b/drivers/watchdog/xilinx_wwdt.c
@@ -90,9 +90,8 @@ static int xlnx_wwdt_start(struct udevice *dev, u64 timeout, ulong flags)
/* Calculate timeout count */
count = timeout * clock_f;
- /* clk_enable will return -ENOSYS when it is not implemented */
ret = clk_enable(&wdt->clk);
- if (ret && ret != -ENOSYS) {
+ if (ret) {
dev_err(dev, "failed to enable clock\n");
return ret;
}