summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c13
-rw-r--r--drivers/ddr/fsl/fsl_ddr_gen4.c42
-rw-r--r--drivers/ddr/fsl/options.c3
-rw-r--r--drivers/gpio/Kconfig15
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/rk_gpio.c1
-rw-r--r--drivers/gpio/tegra186_gpio.c288
-rw-r--r--drivers/gpio/tegra186_gpio_priv.h61
-rw-r--r--drivers/mmc/fsl_esdhc.c9
-rw-r--r--drivers/mmc/tegra_mmc.c32
-rw-r--r--drivers/mtd/spi/sf_params.c1
-rw-r--r--drivers/mtd/spi/spi_flash.c5
-rw-r--r--drivers/pci/pcie_layerscape.c9
13 files changed, 445 insertions, 35 deletions
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 9073917..1d5cec6 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -709,7 +709,7 @@ static void set_timing_cfg_2(const unsigned int ctrl_num,
| ((add_lat_mclk & 0xf) << 28)
| ((cpo & 0x1f) << 23)
| ((wr_lat & 0xf) << 19)
- | ((wr_lat & 0x10) << 14)
+ | ((wr_lat & 0x10) << 18)
| ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT)
| ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT)
| ((cke_pls & 0x7) << 6)
@@ -1835,10 +1835,17 @@ static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,
/* Per FSL Application Note: AN2805 */
ss_en = 1;
#endif
- clk_adjust = popts->clk_adjust;
+ if (fsl_ddr_get_version(0) >= 0x40701) {
+ /* clk_adjust in 5-bits on T-series and LS-series */
+ clk_adjust = (popts->clk_adjust & 0x1F) << 22;
+ } else {
+ /* clk_adjust in 4-bits on earlier MPC85xx and P-series */
+ clk_adjust = (popts->clk_adjust & 0xF) << 23;
+ }
+
ddr->ddr_sdram_clk_cntl = (0
| ((ss_en & 0x1) << 31)
- | ((clk_adjust & 0xF) << 23)
+ | clk_adjust
);
debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl);
}
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index 5039f5d..d37e247 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -206,12 +206,14 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
#ifdef CONFIG_SYS_FSL_ERRATUM_A009803
/* part 1 of 2 */
- if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */
- ddr_out32(&ddr->ddr_sdram_rcw_2,
- regs->ddr_sdram_rcw_2 & ~0x0f000000);
+ if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
+ if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */
+ ddr_out32(&ddr->ddr_sdram_rcw_2,
+ regs->ddr_sdram_rcw_2 & ~0x0f000000);
+ }
+ ddr_out32(&ddr->err_disable, regs->err_disable |
+ DDR_ERR_DISABLE_APED);
}
-
- ddr_out32(&ddr->err_disable, regs->err_disable | DDR_ERR_DISABLE_APED);
#else
ddr_out32(&ddr->err_disable, regs->err_disable);
#endif
@@ -395,22 +397,24 @@ step2:
#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */
#ifdef CONFIG_SYS_FSL_ERRATUM_A009803
- /* if it's RDIMM */
- if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) {
- for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
- if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
- continue;
- set_wait_for_bits_clear(&ddr->sdram_md_cntl,
- MD_CNTL_MD_EN |
- MD_CNTL_CS_SEL(i) |
- 0x070000ed,
- MD_CNTL_MD_EN);
- udelay(1);
+ if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
+ /* if it's RDIMM */
+ if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) {
+ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+ if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
+ continue;
+ set_wait_for_bits_clear(&ddr->sdram_md_cntl,
+ MD_CNTL_MD_EN |
+ MD_CNTL_CS_SEL(i) |
+ 0x070000ed,
+ MD_CNTL_MD_EN);
+ udelay(1);
+ }
}
- }
- ddr_out32(&ddr->err_disable,
- regs->err_disable & ~DDR_ERR_DISABLE_APED);
+ ddr_out32(&ddr->err_disable,
+ regs->err_disable & ~DDR_ERR_DISABLE_APED);
+ }
#endif
}
#endif
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index d0075ff..793d12a 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -886,7 +886,8 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm,
} else
popts->ecc_mode = 1;
#endif
- popts->ecc_init_using_memctl = 1; /* 0 = use DMA, 1 = use memctl */
+ /* 1 = use memory controler to init data */
+ popts->ecc_init_using_memctl = popts->ecc_mode ? 1 : 0;
/*
* Choose DQS config
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 93a7e8c..32219ed 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -109,6 +109,21 @@ config SANDBOX_GPIO_COUNT
of 'anonymous' GPIOs that do not belong to any device or bank.
Select a suitable value depending on your needs.
+config TEGRA_GPIO
+ bool "Tegra20..210 GPIO driver"
+ depends on DM_GPIO
+ help
+ Support for the GPIO controller contained in NVIDIA Tegra20 through
+ Tegra210.
+
+config TEGRA186_GPIO
+ bool "Tegra186 GPIO driver"
+ depends on DM_GPIO
+ help
+ Support for the GPIO controller contained in NVIDIA Tegra186. This
+ covers both the "main" and "AON" controller instances, even though
+ they have slightly different register layout.
+
config GPIO_UNIPHIER
bool "UniPhier GPIO"
depends on ARCH_UNIPHIER
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ddec1ef..3c43101 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_S5P) += s5p_gpio.o
obj-$(CONFIG_SANDBOX_GPIO) += sandbox.o
obj-$(CONFIG_SPEAR_GPIO) += spear_gpio.o
obj-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o
+obj-$(CONFIG_TEGRA186_GPIO) += tegra186_gpio.o
obj-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o
obj-$(CONFIG_DM644X_GPIO) += da8xx_gpio.o
obj-$(CONFIG_ALTERA_PIO) += altera_pio.o
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index fefe3ca..64abcba 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -8,7 +8,6 @@
*/
#include <common.h>
-#include <clk.h>
#include <dm.h>
#include <syscon.h>
#include <asm/errno.h>
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
new file mode 100644
index 0000000..1c68151
--- /dev/null
+++ b/drivers/gpio/tegra186_gpio.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2010-2016, NVIDIA CORPORATION.
+ * (based on tegra_gpio.c)
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/gpio.h>
+#include <dm/device-internal.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "tegra186_gpio_priv.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct tegra186_gpio_port_data {
+ const char *name;
+ uint32_t offset;
+};
+
+struct tegra186_gpio_ctlr_data {
+ const struct tegra186_gpio_port_data *ports;
+ uint32_t port_count;
+};
+
+struct tegra186_gpio_platdata {
+ const char *name;
+ uint32_t *regs;
+};
+
+static uint32_t *tegra186_gpio_reg(struct udevice *dev, uint32_t reg,
+ uint32_t gpio)
+{
+ struct tegra186_gpio_platdata *plat = dev->platdata;
+ uint32_t index = (reg + (gpio * TEGRA186_GPIO_PER_GPIO_STRIDE)) / 4;
+
+ return &(plat->regs[index]);
+}
+
+static int tegra186_gpio_set_out(struct udevice *dev, unsigned offset,
+ bool output)
+{
+ uint32_t *reg;
+ uint32_t rval;
+
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_CONTROL, offset);
+ rval = readl(reg);
+ if (output)
+ rval &= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
+ else
+ rval |= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
+ writel(rval, reg);
+
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
+ rval = readl(reg);
+ if (output)
+ rval |= TEGRA186_GPIO_ENABLE_CONFIG_OUT;
+ else
+ rval &= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT;
+ rval |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE;
+ writel(rval, reg);
+
+ return 0;
+}
+
+static int tegra186_gpio_set_val(struct udevice *dev, unsigned offset, bool val)
+{
+ uint32_t *reg;
+ uint32_t rval;
+
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE, offset);
+ rval = readl(reg);
+ if (val)
+ rval |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
+ else
+ rval &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
+ writel(rval, reg);
+
+ return 0;
+}
+
+static int tegra186_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+ return tegra186_gpio_set_out(dev, offset, false);
+}
+
+static int tegra186_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
+{
+ int ret;
+
+ ret = tegra186_gpio_set_val(dev, offset, value != 0);
+ if (ret)
+ return ret;
+ return tegra186_gpio_set_out(dev, offset, true);
+}
+
+static int tegra186_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+ uint32_t *reg;
+ uint32_t rval;
+
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
+ rval = readl(reg);
+
+ if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE,
+ offset);
+ else
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_INPUT, offset);
+
+ rval = readl(reg);
+ return !!rval;
+}
+
+static int tegra186_gpio_set_value(struct udevice *dev, unsigned offset,
+ int value)
+{
+ return tegra186_gpio_set_val(dev, offset, value != 0);
+}
+
+static int tegra186_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+ uint32_t *reg;
+ uint32_t rval;
+
+ reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
+ rval = readl(reg);
+ if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
+ return GPIOF_OUTPUT;
+ else
+ return GPIOF_INPUT;
+}
+
+static int tegra186_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args)
+{
+ int gpio, port, ret;
+
+ gpio = args->args[0];
+ port = gpio / TEGRA186_GPIO_PER_GPIO_COUNT;
+ ret = device_get_child(dev, port, &desc->dev);
+ if (ret)
+ return ret;
+ desc->offset = gpio % TEGRA186_GPIO_PER_GPIO_COUNT;
+ desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops tegra186_gpio_ops = {
+ .direction_input = tegra186_gpio_direction_input,
+ .direction_output = tegra186_gpio_direction_output,
+ .get_value = tegra186_gpio_get_value,
+ .set_value = tegra186_gpio_set_value,
+ .get_function = tegra186_gpio_get_function,
+ .xlate = tegra186_gpio_xlate,
+};
+
+/**
+ * We have a top-level GPIO device with no actual GPIOs. It has a child device
+ * for each port within the controller.
+ */
+static int tegra186_gpio_bind(struct udevice *parent)
+{
+ struct tegra186_gpio_platdata *parent_plat = parent->platdata;
+ struct tegra186_gpio_ctlr_data *ctlr_data =
+ (struct tegra186_gpio_ctlr_data *)dev_get_driver_data(parent);
+ uint32_t *regs;
+ int port, ret;
+
+ /* If this is a child device, there is nothing to do here */
+ if (parent_plat)
+ return 0;
+
+ regs = (uint32_t *)dev_get_addr_name(parent, "gpio");
+ if (regs == (uint32_t *)FDT_ADDR_T_NONE)
+ return -ENODEV;
+
+ for (port = 0; port < ctlr_data->port_count; port++) {
+ struct tegra186_gpio_platdata *plat;
+ struct udevice *dev;
+
+ plat = calloc(1, sizeof(*plat));
+ if (!plat)
+ return -ENOMEM;
+ plat->name = ctlr_data->ports[port].name;
+ plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);
+
+ ret = device_bind(parent, parent->driver, plat->name, plat,
+ -1, &dev);
+ if (ret)
+ return ret;
+ dev->of_offset = parent->of_offset;
+ }
+
+ return 0;
+}
+
+static int tegra186_gpio_probe(struct udevice *dev)
+{
+ struct tegra186_gpio_platdata *plat = dev->platdata;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ /* Only child devices have ports */
+ if (!plat)
+ return 0;
+
+ uc_priv->gpio_count = TEGRA186_GPIO_PER_GPIO_COUNT;
+ uc_priv->bank_name = plat->name;
+
+ return 0;
+}
+
+static const struct tegra186_gpio_port_data tegra186_gpio_main_ports[] = {
+ {"A", 0x2000},
+ {"B", 0x3000},
+ {"C", 0x3200},
+ {"D", 0x3400},
+ {"E", 0x2200},
+ {"F", 0x2400},
+ {"G", 0x4200},
+ {"H", 0x1000},
+ {"I", 0x0800},
+ {"J", 0x5000},
+ {"K", 0x5200},
+ {"L", 0x1200},
+ {"M", 0x5600},
+ {"N", 0x0000},
+ {"O", 0x0200},
+ {"P", 0x4000},
+ {"Q", 0x0400},
+ {"R", 0x0a00},
+ {"T", 0x0600},
+ {"X", 0x1400},
+ {"Y", 0x1600},
+ {"BB", 0x2600},
+ {"CC", 0x5400},
+};
+
+static const struct tegra186_gpio_ctlr_data tegra186_gpio_main_data = {
+ .ports = tegra186_gpio_main_ports,
+ .port_count = ARRAY_SIZE(tegra186_gpio_main_ports),
+};
+
+static const struct tegra186_gpio_port_data tegra186_gpio_aon_ports[] = {
+ {"S", 0x0200},
+ {"U", 0x0400},
+ {"V", 0x0800},
+ {"W", 0x0a00},
+ {"Z", 0x0e00},
+ {"AA", 0x0c00},
+ {"EE", 0x0600},
+ {"FF", 0x0000},
+};
+
+static const struct tegra186_gpio_ctlr_data tegra186_gpio_aon_data = {
+ .ports = tegra186_gpio_aon_ports,
+ .port_count = ARRAY_SIZE(tegra186_gpio_aon_ports),
+};
+
+static const struct udevice_id tegra186_gpio_ids[] = {
+ {
+ .compatible = "nvidia,tegra186-gpio",
+ .data = (ulong)&tegra186_gpio_main_data,
+ },
+ {
+ .compatible = "nvidia,tegra186-gpio-aon",
+ .data = (ulong)&tegra186_gpio_aon_data,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(tegra186_gpio) = {
+ .name = "tegra186_gpio",
+ .id = UCLASS_GPIO,
+ .of_match = tegra186_gpio_ids,
+ .bind = tegra186_gpio_bind,
+ .probe = tegra186_gpio_probe,
+ .ops = &tegra186_gpio_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/gpio/tegra186_gpio_priv.h b/drivers/gpio/tegra186_gpio_priv.h
new file mode 100644
index 0000000..9e85a434
--- /dev/null
+++ b/drivers/gpio/tegra186_gpio_priv.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _TEGRA186_GPIO_PRIV_H_
+#define _TEGRA186_GPIO_PRIV_H_
+
+/*
+ * For each GPIO, there are a set of registers than affect it, all packed
+ * back-to-back.
+ */
+#define TEGRA186_GPIO_ENABLE_CONFIG 0x00
+#define TEGRA186_GPIO_ENABLE_CONFIG_ENABLE BIT(0)
+#define TEGRA186_GPIO_ENABLE_CONFIG_OUT BIT(1)
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SHIFT 2
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_MASK 3
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_NONE 0
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL 1
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE 2
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_DOUBLE_EDGE 3
+#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL_HIGH_RISING BIT(4)
+#define TEGRA186_GPIO_ENABLE_CONFIG_DEBOUNCE_ENABLE BIT(5)
+#define TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT_ENABLE BIT(6)
+#define TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMPING_ENABLE BIT(7)
+
+#define TEGRA186_GPIO_DEBOUNCE_THRESHOLD 0x04
+
+#define TEGRA186_GPIO_INPUT 0x08
+
+#define TEGRA186_GPIO_OUTPUT_CONTROL 0x0c
+#define TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED BIT(0)
+
+#define TEGRA186_GPIO_OUTPUT_VALUE 0x10
+#define TEGRA186_GPIO_OUTPUT_VALUE_HIGH 1
+
+#define TEGRA186_GPIO_INTERRUPT_CLEAR 0x14
+
+/*
+ * 8 GPIOs are packed into a port. Their registers appear back-to-back in the
+ * port's address space.
+ */
+#define TEGRA186_GPIO_PER_GPIO_STRIDE 0x20
+#define TEGRA186_GPIO_PER_GPIO_COUNT 8
+
+/*
+ * Per-port registers are packed immediately following all of a port's
+ * per-GPIO registers.
+ */
+#define TEGRA186_GPIO_INTERRUPT_STATUS_G 0x100
+#define TEGRA186_GPIO_INTERRUPT_STATUS_G_STRIDE 4
+#define TEGRA186_GPIO_INTERRUPT_STATUS_G_COUNT 8
+
+/*
+ * The registers for multiple ports are packed together back-to-back to form
+ * the overall controller.
+ */
+#define TEGRA186_GPIO_PER_PORT_STRIDE 0x200
+
+#endif
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 3acf9e8..57ad975 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -308,14 +308,10 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
static void check_and_invalidate_dcache_range
(struct mmc_cmd *cmd,
struct mmc_data *data) {
-#ifdef CONFIG_FSL_LAYERSCAPE
unsigned start = 0;
-#else
- unsigned start = (unsigned)data->dest ;
-#endif
+ unsigned end = 0;
unsigned size = roundup(ARCH_DMA_MINALIGN,
data->blocks*data->blocksize);
- unsigned end = start+size ;
#ifdef CONFIG_FSL_LAYERSCAPE
dma_addr_t addr;
@@ -324,7 +320,10 @@ static void check_and_invalidate_dcache_range
printf("Error found for upper 32 bits\n");
else
start = lower_32_bits(addr);
+#else
+ start = (unsigned)data->dest;
#endif
+ end = start + size;
invalidate_dcache_range(start, end);
}
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 573819a..c9d9432 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -11,8 +11,10 @@
#include <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#ifndef CONFIG_TEGRA186
#include <asm/arch/clock.h>
#include <asm/arch-tegra/clk_rst.h>
+#endif
#include <asm/arch-tegra/mmc.h>
#include <asm/arch-tegra/tegra_mmc.h>
#include <mmc.h>
@@ -357,8 +359,12 @@ static void mmc_change_clock(struct mmc_host *host, uint clock)
*/
if (clock == 0)
goto out;
+#ifndef CONFIG_TEGRA186
clock_adjust_periph_pll_div(host->mmc_id, CLOCK_ID_PERIPH, clock,
&div);
+#else
+ div = (20000000 + clock - 1) / clock;
+#endif
debug("div = %d\n", div);
writew(0, &host->reg->clkcon);
@@ -543,7 +549,9 @@ static int do_mmc_init(int dev_index, bool removable)
gpio_get_number(&host->cd_gpio));
host->clock = 0;
+#ifndef CONFIG_TEGRA186
clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000);
+#endif
if (dm_gpio_is_valid(&host->pwr_gpio))
dm_gpio_set_value(&host->pwr_gpio, 1);
@@ -568,7 +576,11 @@ static int do_mmc_init(int dev_index, bool removable)
* (actually 52MHz)
*/
host->cfg.f_min = 375000;
+#ifndef CONFIG_TEGRA186
host->cfg.f_max = 48000000;
+#else
+ host->cfg.f_max = 375000;
+#endif
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
@@ -600,11 +612,13 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
return -FDT_ERR_NOTFOUND;
}
+#ifndef CONFIG_TEGRA186
host->mmc_id = clock_decode_periph_id(blob, node);
if (host->mmc_id == PERIPH_ID_NONE) {
debug("%s: could not decode periph id\n", __func__);
return -FDT_ERR_NOTFOUND;
}
+#endif
/*
* NOTE: mmc->bus_width is determined by mmc.c dynamically.
@@ -624,7 +638,13 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
*removablep = !fdtdec_get_bool(blob, node, "non-removable");
debug("%s: found controller at %p, width = %d, periph_id = %d\n",
- __func__, host->reg, host->width, host->mmc_id);
+ __func__, host->reg, host->width,
+#ifndef CONFIG_TEGRA186
+ host->mmc_id
+#else
+ -1
+#endif
+ );
return 0;
}
@@ -668,6 +688,16 @@ void tegra_mmc_init(void)
const void *blob = gd->fdt_blob;
debug("%s entry\n", __func__);
+ /* See if any Tegra186 MMC controllers are present */
+ count = fdtdec_find_aliases_for_id(blob, "sdhci",
+ COMPAT_NVIDIA_TEGRA186_SDMMC, node_list,
+ CONFIG_SYS_MMC_MAX_DEVICE);
+ debug("%s: count of Tegra186 sdhci nodes is %d\n", __func__, count);
+ if (process_nodes(blob, node_list, count)) {
+ printf("%s: Error processing T186 mmc node(s)!\n", __func__);
+ return;
+ }
+
/* See if any Tegra210 MMC controllers are present */
count = fdtdec_find_aliases_for_id(blob, "sdhci",
COMPAT_NVIDIA_TEGRA210_SDMMC, node_list,
diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
index 4f37e33..c577d9e 100644
--- a/drivers/mtd/spi/sf_params.c
+++ b/drivers/mtd/spi/sf_params.c
@@ -67,6 +67,7 @@ const struct spi_flash_params spi_flash_params_table[] = {
{"S25FL128S_64K", 0x012018, 0x4d01, 64 * 1024, 256, RD_FULL, WR_QPP},
{"S25FL256S_256K", 0x010219, 0x4d00, 256 * 1024, 128, RD_FULL, WR_QPP},
{"S25FL256S_64K", 0x010219, 0x4d01, 64 * 1024, 512, RD_FULL, WR_QPP},
+ {"S25FS512S", 0x010220, 0x4D00, 128 * 1024, 512, RD_FULL, WR_QPP},
{"S25FL512S_256K", 0x010220, 0x4d00, 256 * 1024, 256, RD_FULL, WR_QPP},
{"S25FL512S_64K", 0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL, WR_QPP},
{"S25FL512S_512K", 0x010220, 0x4f00, 256 * 1024, 256, RD_FULL, WR_QPP},
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index fa0e799..64d4e0f 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -1072,7 +1072,8 @@ int spi_flash_scan(struct spi_flash *flash)
* sector that is not overlaid by the parameter sectors.
* The uniform sector erase command has no effect on parameter sectors.
*/
- if (jedec == 0x0219 && (ext_jedec & 0xff00) == 0x4d00) {
+ if ((jedec == 0x0219 || (jedec == 0x0220)) &&
+ (ext_jedec & 0xff00) == 0x4d00) {
int ret;
u8 id[6];
@@ -1146,7 +1147,7 @@ int spi_flash_scan(struct spi_flash *flash)
* have 256b pages.
*/
if (ext_jedec == 0x4d00) {
- if ((jedec == 0x0215) || (jedec == 0x216))
+ if ((jedec == 0x0215) || (jedec == 0x216) || (jedec == 0x220))
flash->page_size = 256;
else
flash->page_size = 512;
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 0ba960e..2e6b986 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -569,7 +569,7 @@ static void fdt_fixup_pcie(void *blob)
unsigned char header_type;
int index;
u32 streamid;
- pci_dev_t dev;
+ pci_dev_t dev, bdf;
int bus;
unsigned short id;
struct pci_controller *hose;
@@ -611,12 +611,15 @@ static void fdt_fixup_pcie(void *blob)
continue;
}
+ /* the DT fixup must be relative to the hose first_busno */
+ bdf = dev - PCI_BDF(hose->first_busno, 0, 0);
+
/* map PCI b.d.f to streamID in LUT */
- ls_pcie_lut_set_mapping(pcie, index, dev >> 8,
+ ls_pcie_lut_set_mapping(pcie, index, bdf >> 8,
streamid);
/* update msi-map in device tree */
- fdt_pcie_set_msi_map_entry(blob, pcie, dev >> 8,
+ fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8,
streamid);
}
}