aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-11-04 12:57:41 -0500
committerTom Rini <trini@konsulko.com>2019-11-04 12:57:41 -0500
commit73b6e6ad254b36763419cdd3fdf406c0094517b7 (patch)
treef432e1b568809834c52389b5075815700bc68026 /drivers
parent3b02d614b429442333ec3d82eef0bba527be4f8c (diff)
parentae8a53ece0ff3b1ed686c3e0af14e59973d25db8 (diff)
downloadu-boot-73b6e6ad254b36763419cdd3fdf406c0094517b7.zip
u-boot-73b6e6ad254b36763419cdd3fdf406c0094517b7.tar.gz
u-boot-73b6e6ad254b36763419cdd3fdf406c0094517b7.tar.bz2
Merge tag 'u-boot-imx-20191104' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20191104 ------------------- - i.MX NAND: nandbcb support for MX6UL / i.MX7 - i.MX8: support for HAB - Convert to DM (opos6ul, mccmon6) - Toradex i.MX6ull colibri - sync DTS with kernel Travis : https://travis-ci.org/sbabic/u-boot-imx/builds/606853416
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/imx8/fuse.c2
-rw-r--r--drivers/mtd/nand/raw/mxs_nand.c116
-rw-r--r--drivers/power/domain/imx8m-power-domain.c6
-rw-r--r--drivers/power/pmic/Kconfig8
-rw-r--r--drivers/power/pmic/bd71837.c2
-rw-r--r--drivers/video/mxsfb.c1
-rw-r--r--drivers/watchdog/imx_watchdog.c41
7 files changed, 158 insertions, 18 deletions
diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c
index 2f2fad2..1309215 100644
--- a/drivers/misc/imx8/fuse.c
+++ b/drivers/misc/imx8/fuse.c
@@ -74,7 +74,7 @@ int fuse_prog(u32 bank, u32 word, u32 val)
}
return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word,
- (unsigned long)val, 0);
+ (unsigned long)val, 0, 0);
}
int fuse_override(u32 bank, u32 word, u32 val)
diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c
index a41b962..ad7b644 100644
--- a/drivers/mtd/nand/raw/mxs_nand.c
+++ b/drivers/mtd/nand/raw/mxs_nand.c
@@ -740,6 +740,19 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
+ if (is_mx7() && nand_info->en_randomizer) {
+ d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
+ GPMI_ECCCTRL_RANDOMIZER_TYPE2;
+ /*
+ * Write NAND page number needed to be randomized
+ * to GPMI_ECCCOUNT register.
+ *
+ * The value is between 0-255. For additional details
+ * check 9.6.6.4 of i.MX7D Applications Processor reference
+ */
+ d->cmd.pio_words[3] |= (page % 255) << 16;
+ }
+
mxs_dma_desc_append(channel, d);
/* Flush caches */
@@ -1003,6 +1016,10 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
uint32_t tmp;
int ret;
+ nand_info->en_randomizer = 0;
+ nand_info->oobsize = mtd->oobsize;
+ nand_info->writesize = mtd->writesize;
+
ret = mxs_nand_set_geometry(mtd, geo);
if (ret)
return ret;
@@ -1020,6 +1037,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
tmp |= (geo->gf_len == 14 ? 1 : 0) <<
BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
writel(tmp, &bch_regs->hw_bch_flash0layout0);
+ nand_info->bch_flash0layout0 = tmp;
tmp = (mtd->writesize + mtd->oobsize)
<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
@@ -1028,6 +1046,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
tmp |= (geo->gf_len == 14 ? 1 : 0) <<
BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
writel(tmp, &bch_regs->hw_bch_flash0layout1);
+ nand_info->bch_flash0layout1 = tmp;
/* Set *all* chip selects to use layout 0 */
writel(0, &bch_regs->hw_bch_layoutselect);
@@ -1303,3 +1322,100 @@ err:
free(nand_info);
}
#endif
+
+/*
+ * Read NAND layout for FCB block generation.
+ */
+void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l)
+{
+ struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
+ u32 tmp;
+
+ tmp = readl(&bch_regs->hw_bch_flash0layout0);
+ l->nblocks = (tmp & BCH_FLASHLAYOUT0_NBLOCKS_MASK) >>
+ BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
+ l->meta_size = (tmp & BCH_FLASHLAYOUT0_META_SIZE_MASK) >>
+ BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
+
+ tmp = readl(&bch_regs->hw_bch_flash0layout1);
+ l->data0_size = 4 * ((tmp & BCH_FLASHLAYOUT0_DATA0_SIZE_MASK) >>
+ BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET);
+ l->ecc0 = (tmp & BCH_FLASHLAYOUT0_ECC0_MASK) >>
+ BCH_FLASHLAYOUT0_ECC0_OFFSET;
+ l->datan_size = 4 * ((tmp & BCH_FLASHLAYOUT1_DATAN_SIZE_MASK) >>
+ BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET);
+ l->eccn = (tmp & BCH_FLASHLAYOUT1_ECCN_MASK) >>
+ BCH_FLASHLAYOUT1_ECCN_OFFSET;
+}
+
+/*
+ * Set BCH to specific layout used by ROM bootloader to read FCB.
+ */
+void mxs_nand_mode_fcb(struct mtd_info *mtd)
+{
+ u32 tmp;
+ struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
+
+ nand_info->en_randomizer = 1;
+
+ mtd->writesize = 1024;
+ mtd->oobsize = 1862 - 1024;
+
+ /* 8 ecc_chunks_*/
+ tmp = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
+ /* 32 bytes for metadata */
+ tmp |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
+ /* using ECC62 level to be performed */
+ tmp |= 0x1F << BCH_FLASHLAYOUT0_ECC0_OFFSET;
+ /* 0x20 * 4 bytes of the data0 block */
+ tmp |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET;
+ tmp |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
+ writel(tmp, &bch_regs->hw_bch_flash0layout0);
+
+ /* 1024 for data + 838 for OOB */
+ tmp = 1862 << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
+ /* using ECC62 level to be performed */
+ tmp |= 0x1F << BCH_FLASHLAYOUT1_ECCN_OFFSET;
+ /* 0x20 * 4 bytes of the data0 block */
+ tmp |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET;
+ tmp |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
+ writel(tmp, &bch_regs->hw_bch_flash0layout1);
+}
+
+/*
+ * Restore BCH to normal settings.
+ */
+void mxs_nand_mode_normal(struct mtd_info *mtd)
+{
+ struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
+
+ nand_info->en_randomizer = 0;
+
+ mtd->writesize = nand_info->writesize;
+ mtd->oobsize = nand_info->oobsize;
+
+ writel(nand_info->bch_flash0layout0, &bch_regs->hw_bch_flash0layout0);
+ writel(nand_info->bch_flash0layout1, &bch_regs->hw_bch_flash0layout1);
+}
+
+uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+ struct bch_geometry *geo = &nand_info->bch_geometry;
+
+ return geo->block_mark_byte_offset;
+}
+
+uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+ struct bch_geometry *geo = &nand_info->bch_geometry;
+
+ return geo->block_mark_bit_offset;
+}
diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c
index 164fb3d..40ece9e 100644
--- a/drivers/power/domain/imx8m-power-domain.c
+++ b/drivers/power/domain/imx8m-power-domain.c
@@ -37,7 +37,8 @@ static int imx8m_power_domain_on(struct power_domain *power_domain)
if (pdata->has_pd)
power_domain_on(&pdata->pd);
- call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, pdata->resource_id, 1);
+ call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
+ pdata->resource_id, 1, 0);
return 0;
}
@@ -51,7 +52,8 @@ static int imx8m_power_domain_off(struct power_domain *power_domain)
if (pdata->resource_id < 0)
return -EINVAL;
- call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, pdata->resource_id, 0);
+ call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
+ pdata->resource_id, 0, 0);
if (pdata->has_pd)
power_domain_off(&pdata->pd);
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 586772f..4718dc7 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -55,6 +55,14 @@ config DM_PMIC_BD71837
This config enables implementation of driver-model pmic uclass features
for PMIC BD71837. The driver implements read/write operations.
+config SPL_DM_PMIC_BD71837
+ bool "Enable Driver Model for PMIC BD71837 in SPL stage"
+ depends on DM_PMIC
+ help
+ This config enables implementation of driver-model pmic uclass
+ features for PMIC BD71837. The driver implements read/write
+ operations.
+
config DM_PMIC_FAN53555
bool "Enable support for OnSemi FAN53555"
depends on DM_PMIC && DM_REGULATOR && DM_I2C
diff --git a/drivers/power/pmic/bd71837.c b/drivers/power/pmic/bd71837.c
index e292d42..2e04298 100644
--- a/drivers/power/pmic/bd71837.c
+++ b/drivers/power/pmic/bd71837.c
@@ -3,8 +3,6 @@
* Copyright 2018 NXP
*/
-#define DEBUG
-
#include <common.h>
#include <errno.h>
#include <dm.h>
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 6922a13..c529810 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -367,6 +367,7 @@ static int mxs_video_probe(struct udevice *dev)
mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
DCACHE_WRITEBACK);
video_set_flush_dcache(dev, true);
+ gd->fb_base = plat->base;
return ret;
}
diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c
index 53a3e9f..c030360 100644
--- a/drivers/watchdog/imx_watchdog.c
+++ b/drivers/watchdog/imx_watchdog.c
@@ -15,15 +15,23 @@
#endif
#include <fsl_wdog.h>
-static void imx_watchdog_expire_now(struct watchdog_regs *wdog)
+static void imx_watchdog_expire_now(struct watchdog_regs *wdog, bool ext_reset)
{
- clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
+ u16 wcr = WCR_WDE;
+
+ if (ext_reset)
+ wcr |= WCR_SRS; /* do not assert internal reset */
+ else
+ wcr |= WCR_WDA; /* do not assert external reset */
+
+ /* Write 3 times to ensure it works, due to IMX6Q errata ERR004346 */
+ writew(wcr, &wdog->wcr);
+ writew(wcr, &wdog->wcr);
+ writew(wcr, &wdog->wcr);
- writew(0x5555, &wdog->wsr);
- writew(0xaaaa, &wdog->wsr); /* load minimum 1/2 second timeout */
while (1) {
/*
- * spin for .5 seconds before reset
+ * spin before reset
*/
}
}
@@ -34,7 +42,7 @@ void __attribute__((weak)) reset_cpu(ulong addr)
{
struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
- imx_watchdog_expire_now(wdog);
+ imx_watchdog_expire_now(wdog, true);
}
#endif
@@ -47,9 +55,10 @@ static void imx_watchdog_reset(struct watchdog_regs *wdog)
#endif /* CONFIG_WATCHDOG_RESET_DISABLE*/
}
-static void imx_watchdog_init(struct watchdog_regs *wdog)
+static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset)
{
u16 timeout;
+ u16 wcr;
/*
* The timer watchdog can be set between
@@ -61,11 +70,14 @@ static void imx_watchdog_init(struct watchdog_regs *wdog)
#endif
timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1;
#ifdef CONFIG_FSL_LSCH2
- writew((WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout, &wdog->wcr);
+ wcr = (WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout;
#else
- writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS |
- WCR_WDA | SET_WCR_WT(timeout), &wdog->wcr);
+ wcr = WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_SRS |
+ WCR_WDA | SET_WCR_WT(timeout);
+ if (ext_reset)
+ wcr |= WCR_WDT;
#endif /* CONFIG_FSL_LSCH2*/
+ writew(wcr, &wdog->wcr);
imx_watchdog_reset(wdog);
}
@@ -81,11 +93,12 @@ void hw_watchdog_init(void)
{
struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
- imx_watchdog_init(wdog);
+ imx_watchdog_init(wdog, true);
}
#else
struct imx_wdt_priv {
void __iomem *base;
+ bool ext_reset;
};
static int imx_wdt_reset(struct udevice *dev)
@@ -101,7 +114,7 @@ static int imx_wdt_expire_now(struct udevice *dev, ulong flags)
{
struct imx_wdt_priv *priv = dev_get_priv(dev);
- imx_watchdog_expire_now(priv->base);
+ imx_watchdog_expire_now(priv->base, priv->ext_reset);
hang();
return 0;
@@ -111,7 +124,7 @@ static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
struct imx_wdt_priv *priv = dev_get_priv(dev);
- imx_watchdog_init(priv->base);
+ imx_watchdog_init(priv->base, priv->ext_reset);
return 0;
}
@@ -124,6 +137,8 @@ static int imx_wdt_probe(struct udevice *dev)
if (!priv->base)
return -ENOENT;
+ priv->ext_reset = dev_read_bool(dev, "fsl,ext-reset-output");
+
return 0;
}