diff options
author | Tom Rini <trini@konsulko.com> | 2019-06-11 13:41:24 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2019-06-11 13:41:24 -0400 |
commit | 529faf80c339b78bd361b59735664f2605322b8e (patch) | |
tree | 2186ebe6f8f713d0dd497eb9d20c1a30e64105bb /drivers | |
parent | 68b90e57bc034e237923b02acb633dc4e91d44cb (diff) | |
parent | 23612534fe0fe426716ee9cb5cfeb74a456cb891 (diff) | |
download | u-boot-529faf80c339b78bd361b59735664f2605322b8e.tar.gz |
Merge tag 'u-boot-imx-20190612' of git://git.denx.de/u-boot-imx
u-boot-imx-20190612
--------------------
- Board fixes:
- imx6logic
- wandboard
- mx6sabre boots again
- imx8qm_mek
- pico-* boards
- Toradex apalis / colibri
- engicam imx6 (environment)
- KP MX53
- opos6ul
- Switch to DM:
- vining2000
- dh MX6
- Toradex colibri i.MX7
- Novena
- Security : fix CSF size for HAB
- Other:
- imx: fix building for i.mx8 without spl
- pcie and switch to DM
mx6sabreauto: Enable SPL SDP support
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/imx/clk-imx8qm.c | 18 | ||||
-rw-r--r-- | drivers/crypto/fsl/jr.c | 9 | ||||
-rw-r--r-- | drivers/crypto/fsl/jr.h | 2 | ||||
-rw-r--r-- | drivers/misc/imx8/fuse.c | 2 | ||||
-rw-r--r-- | drivers/net/fec_mxc.c | 2 | ||||
-rw-r--r-- | drivers/pci/pcie_imx.c | 220 | ||||
-rw-r--r-- | drivers/pinctrl/nxp/pinctrl-imx6.c | 2 | ||||
-rw-r--r-- | drivers/power/pmic/Kconfig | 7 | ||||
-rw-r--r-- | drivers/power/pmic/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/pmic/bd71837.c | 89 | ||||
-rw-r--r-- | drivers/power/regulator/pfuze100.c | 4 | ||||
-rw-r--r-- | drivers/serial/serial_mxc.c | 1 | ||||
-rw-r--r-- | drivers/spi/mxc_spi.c | 77 |
13 files changed, 343 insertions, 91 deletions
diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c index 6b5561e178..a6b09d2109 100644 --- a/drivers/clk/imx/clk-imx8qm.c +++ b/drivers/clk/imx/clk-imx8qm.c @@ -80,6 +80,12 @@ ulong imx8_clk_get_rate(struct clk *clk) resource = SC_R_SDHC_1; pm_clk = SC_PM_CLK_PER; break; + case IMX8QM_SDHC2_IPG_CLK: + case IMX8QM_SDHC2_CLK: + case IMX8QM_SDHC2_DIV: + resource = SC_R_SDHC_2; + pm_clk = SC_PM_CLK_PER; + break; case IMX8QM_UART0_IPG_CLK: case IMX8QM_UART0_CLK: resource = SC_R_UART_0; @@ -185,6 +191,12 @@ ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) resource = SC_R_SDHC_1; pm_clk = SC_PM_CLK_PER; break; + case IMX8QM_SDHC2_IPG_CLK: + case IMX8QM_SDHC2_CLK: + case IMX8QM_SDHC2_DIV: + resource = SC_R_SDHC_2; + pm_clk = SC_PM_CLK_PER; + break; case IMX8QM_ENET0_IPG_CLK: case IMX8QM_ENET0_AHB_CLK: case IMX8QM_ENET0_REF_DIV: @@ -273,6 +285,12 @@ int __imx8_clk_enable(struct clk *clk, bool enable) resource = SC_R_SDHC_1; pm_clk = SC_PM_CLK_PER; break; + case IMX8QM_SDHC2_IPG_CLK: + case IMX8QM_SDHC2_CLK: + case IMX8QM_SDHC2_DIV: + resource = SC_R_SDHC_2; + pm_clk = SC_PM_CLK_PER; + break; case IMX8QM_ENET0_IPG_CLK: case IMX8QM_ENET0_AHB_CLK: case IMX8QM_ENET0_REF_DIV: diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index cc8d3b02a5..3121762364 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -578,8 +578,6 @@ int sec_init_idx(uint8_t sec_idx) { ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx); uint32_t mcr = sec_in32(&sec->mcfgr); - uint32_t jrown_ns; - int i; int ret = 0; #ifdef CONFIG_FSL_CORENET @@ -635,13 +633,6 @@ int sec_init_idx(uint8_t sec_idx) #endif #endif - /* Set ownership of job rings to non-TrustZone mode by default */ - for (i = 0; i < ARRAY_SIZE(sec->jrliodnr); i++) { - jrown_ns = sec_in32(&sec->jrliodnr[i].ms); - jrown_ns |= JROWN_NS | JRMID_NS; - sec_out32(&sec->jrliodnr[i].ms, jrown_ns); - } - ret = jr_init(sec_idx); if (ret < 0) { printf("SEC initialization failed\n"); diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h index f6fbb44383..ffd3a19273 100644 --- a/drivers/crypto/fsl/jr.h +++ b/drivers/crypto/fsl/jr.h @@ -33,8 +33,6 @@ #define JRNSLIODN_MASK 0x0fff0000 #define JRSLIODN_SHIFT 0 #define JRSLIODN_MASK 0x00000fff -#define JROWN_NS 0x00000008 -#define JRMID_NS 0x00000001 #define JQ_DEQ_ERR -1 #define JQ_DEQ_TO_ERR -2 diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c index 29d2256a22..2f2fad2c17 100644 --- a/drivers/misc/imx8/fuse.c +++ b/drivers/misc/imx8/fuse.c @@ -15,13 +15,11 @@ DECLARE_GLOBAL_DATA_PTR; #define FSL_ECC_WORD_START_1 0x10 #define FSL_ECC_WORD_END_1 0x10F -#ifdef CONFIG_IMX8QXP #define FSL_ECC_WORD_START_2 0x220 #define FSL_ECC_WORD_END_2 0x31F #define FSL_QXP_FUSE_GAP_START 0x110 #define FSL_QXP_FUSE_GAP_END 0x21F -#endif #define FSL_SIP_OTP_READ 0xc200000A #define FSL_SIP_OTP_WRITE 0xc200000B diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index a672250e16..d7c080943a 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -604,7 +604,7 @@ static int fec_init(struct eth_device *dev, bd_t *bd) writel(0x00000000, &fec->eth->gaddr2); /* Do not access reserved register */ - if (!is_mx6ul() && !is_mx6ull() && !is_imx8m()) { + if (!is_mx6ul() && !is_mx6ull() && !is_imx8() && !is_imx8m()) { /* clear MIB RAM */ for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4) writel(0, i); diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index fcc4ab7139..10b8fb4c88 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -16,6 +16,7 @@ #include <asm/arch/crm_regs.h> #include <asm/gpio.h> #include <asm/io.h> +#include <dm.h> #include <linux/sizes.h> #include <errno.h> #include <asm/arch/sys_proto.h> @@ -92,6 +93,11 @@ #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) #define PCIE_ATU_UPPER_TARGET 0x91C +struct imx_pcie_priv { + void __iomem *dbi_base; + void __iomem *cfg_base; +}; + /* * PHY access functions */ @@ -225,13 +231,13 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data) return 0; } -static int imx6_pcie_link_up(void) +static int imx6_pcie_link_up(struct imx_pcie_priv *priv) { u32 rc, ltssm; int rx_valid, temp; /* link is debug bit 36, debug register 1 starts at bit 32 */ - rc = readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R1); + rc = readl(priv->dbi_base + PCIE_PHY_DEBUG_R1); if ((rc & PCIE_PHY_DEBUG_R1_LINK_UP) && !(rc & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING)) return -EAGAIN; @@ -243,8 +249,8 @@ static int imx6_pcie_link_up(void) * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition * to gen2 is stuck */ - pcie_phy_read((void *)MX6_DBI_ADDR, PCIE_PHY_RX_ASIC_OUT, &rx_valid); - ltssm = readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R0) & 0x3F; + pcie_phy_read(priv->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); + ltssm = readl(priv->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; if (rx_valid & 0x01) return 0; @@ -254,15 +260,15 @@ static int imx6_pcie_link_up(void) printf("transition to gen2 is stuck, reset PHY!\n"); - pcie_phy_read((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, &temp); + pcie_phy_read(priv->dbi_base, PHY_RX_OVRD_IN_LO, &temp); temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN); - pcie_phy_write((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, temp); + pcie_phy_write(priv->dbi_base, PHY_RX_OVRD_IN_LO, temp); udelay(3000); - pcie_phy_read((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, &temp); + pcie_phy_read(priv->dbi_base, PHY_RX_OVRD_IN_LO, &temp); temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN); - pcie_phy_write((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, temp); + pcie_phy_write(priv->dbi_base, PHY_RX_OVRD_IN_LO, temp); return 0; } @@ -270,7 +276,7 @@ static int imx6_pcie_link_up(void) /* * iATU region setup */ -static int imx_pcie_regions_setup(void) +static int imx_pcie_regions_setup(struct imx_pcie_priv *priv) { /* * i.MX6 defines 16MB in the AXI address map for PCIe. @@ -285,24 +291,27 @@ static int imx_pcie_regions_setup(void) */ /* CMD reg:I/O space, MEM space, and Bus Master Enable */ - setbits_le32(MX6_DBI_ADDR | PCI_COMMAND, + setbits_le32(priv->dbi_base + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */ - setbits_le32(MX6_DBI_ADDR + PCI_CLASS_REVISION, + setbits_le32(priv->dbi_base + PCI_CLASS_REVISION, PCI_CLASS_BRIDGE_PCI << 16); /* Region #0 is used for Outbound CFG space access. */ - writel(0, MX6_DBI_ADDR + PCIE_ATU_VIEWPORT); + writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT); - writel(MX6_ROOT_ADDR, MX6_DBI_ADDR + PCIE_ATU_LOWER_BASE); - writel(0, MX6_DBI_ADDR + PCIE_ATU_UPPER_BASE); - writel(MX6_ROOT_ADDR + MX6_ROOT_SIZE, MX6_DBI_ADDR + PCIE_ATU_LIMIT); + writel(lower_32_bits((uintptr_t)priv->cfg_base), + priv->dbi_base + PCIE_ATU_LOWER_BASE); + writel(upper_32_bits((uintptr_t)priv->cfg_base), + priv->dbi_base + PCIE_ATU_UPPER_BASE); + writel(lower_32_bits((uintptr_t)priv->cfg_base + MX6_ROOT_SIZE), + priv->dbi_base + PCIE_ATU_LIMIT); - writel(0, MX6_DBI_ADDR + PCIE_ATU_LOWER_TARGET); - writel(0, MX6_DBI_ADDR + PCIE_ATU_UPPER_TARGET); - writel(PCIE_ATU_TYPE_CFG0, MX6_DBI_ADDR + PCIE_ATU_CR1); - writel(PCIE_ATU_ENABLE, MX6_DBI_ADDR + PCIE_ATU_CR2); + writel(0, priv->dbi_base + PCIE_ATU_LOWER_TARGET); + writel(0, priv->dbi_base + PCIE_ATU_UPPER_TARGET); + writel(PCIE_ATU_TYPE_CFG0, priv->dbi_base + PCIE_ATU_CR1); + writel(PCIE_ATU_ENABLE, priv->dbi_base + PCIE_ATU_CR2); return 0; } @@ -310,23 +319,24 @@ static int imx_pcie_regions_setup(void) /* * PCI Express accessors */ -static uint32_t get_bus_address(pci_dev_t d, int where) +static void __iomem *get_bus_address(struct imx_pcie_priv *priv, + pci_dev_t d, int where) { - uint32_t va_address; + void __iomem *va_address; /* Reconfigure Region #0 */ - writel(0, MX6_DBI_ADDR + PCIE_ATU_VIEWPORT); + writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT); if (PCI_BUS(d) < 2) - writel(PCIE_ATU_TYPE_CFG0, MX6_DBI_ADDR + PCIE_ATU_CR1); + writel(PCIE_ATU_TYPE_CFG0, priv->dbi_base + PCIE_ATU_CR1); else - writel(PCIE_ATU_TYPE_CFG1, MX6_DBI_ADDR + PCIE_ATU_CR1); + writel(PCIE_ATU_TYPE_CFG1, priv->dbi_base + PCIE_ATU_CR1); if (PCI_BUS(d) == 0) { - va_address = MX6_DBI_ADDR; + va_address = priv->dbi_base; } else { - writel(d << 8, MX6_DBI_ADDR + PCIE_ATU_LOWER_TARGET); - va_address = MX6_IO_ADDR + SZ_16M - SZ_1M; + writel(d << 8, priv->dbi_base + PCIE_ATU_LOWER_TARGET); + va_address = priv->cfg_base; } va_address += (where & ~0x3); @@ -374,10 +384,10 @@ static void imx_pcie_fix_dabt_handler(bool set) } } -static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, - int where, u32 *val) +static int imx_pcie_read_cfg(struct imx_pcie_priv *priv, pci_dev_t d, + int where, u32 *val) { - uint32_t va_address; + void __iomem *va_address; int ret; ret = imx_pcie_addr_valid(d); @@ -386,7 +396,7 @@ static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, return 0; } - va_address = get_bus_address(d, where); + va_address = get_bus_address(priv, d, where); /* * Read the PCIe config space. We must replace the DABT handler @@ -403,17 +413,17 @@ static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, return 0; } -static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, - int where, u32 val) +static int imx_pcie_write_cfg(struct imx_pcie_priv *priv, pci_dev_t d, + int where, u32 val) { - uint32_t va_address = 0; + void __iomem *va_address = NULL; int ret; ret = imx_pcie_addr_valid(d); if (ret) return ret; - va_address = get_bus_address(d, where); + va_address = get_bus_address(priv, d, where); /* * Write the PCIe config space. We must replace the DABT handler @@ -430,7 +440,8 @@ static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, /* * Initial bus setup */ -static int imx6_pcie_assert_core_reset(bool prepare_for_boot) +static int imx6_pcie_assert_core_reset(struct imx_pcie_priv *priv, + bool prepare_for_boot) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; @@ -465,12 +476,12 @@ static int imx6_pcie_assert_core_reset(bool prepare_for_boot) gpr12 = readl(&iomuxc_regs->gpr[12]); if ((gpr1 & IOMUXC_GPR1_PCIE_REF_CLK_EN) && (gpr12 & IOMUXC_GPR12_PCIE_CTL_2)) { - val = readl(MX6_DBI_ADDR + PCIE_PL_PFLR); + val = readl(priv->dbi_base + PCIE_PL_PFLR); val &= ~PCIE_PL_PFLR_LINK_STATE_MASK; val |= PCIE_PL_PFLR_FORCE_LINK; imx_pcie_fix_dabt_handler(true); - writel(val, MX6_DBI_ADDR + PCIE_PL_PFLR); + writel(val, priv->dbi_base + PCIE_PL_PFLR); imx_pcie_fix_dabt_handler(false); gpr12 &= ~IOMUXC_GPR12_PCIE_CTL_2; @@ -602,17 +613,17 @@ static int imx6_pcie_deassert_core_reset(void) return 0; } -static int imx_pcie_link_up(void) +static int imx_pcie_link_up(struct imx_pcie_priv *priv) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; uint32_t tmp; int count = 0; - imx6_pcie_assert_core_reset(false); + imx6_pcie_assert_core_reset(priv, false); imx6_pcie_init_phy(); imx6_pcie_deassert_core_reset(); - imx_pcie_regions_setup(); + imx_pcie_regions_setup(priv); /* * By default, the subordinate is set equally to the secondary @@ -621,9 +632,9 @@ static int imx_pcie_link_up(void) * Force the PCIe RC subordinate to 0xff, otherwise no downstream * devices will be detected if the enumeration is applied strictly. */ - tmp = readl(MX6_DBI_ADDR + 0x18); + tmp = readl(priv->dbi_base + 0x18); tmp |= (0xff << 16); - writel(tmp, MX6_DBI_ADDR + 0x18); + writel(tmp, priv->dbi_base + 0x18); /* * FIXME: Force the PCIe RC to Gen1 operation @@ -631,15 +642,15 @@ static int imx_pcie_link_up(void) * up, otherwise no downstream devices are detected. After the * link is up, a managed Gen1->Gen2 transition can be initiated. */ - tmp = readl(MX6_DBI_ADDR + 0x7c); + tmp = readl(priv->dbi_base + 0x7c); tmp &= ~0xf; tmp |= 0x1; - writel(tmp, MX6_DBI_ADDR + 0x7c); + writel(tmp, priv->dbi_base + 0x7c); /* LTSSM enable, starting link. */ setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE); - while (!imx6_pcie_link_up()) { + while (!imx6_pcie_link_up(priv)) { udelay(10); count++; if (count >= 4000) { @@ -647,8 +658,8 @@ static int imx_pcie_link_up(void) puts("PCI: pcie phy link never came up\n"); #endif debug("DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", - readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R0), - readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R1)); + readl(priv->dbi_base + PCIE_PHY_DEBUG_R0), + readl(priv->dbi_base + PCIE_PHY_DEBUG_R1)); return -EINVAL; } } @@ -656,6 +667,30 @@ static int imx_pcie_link_up(void) return 0; } +#if !CONFIG_IS_ENABLED(DM_PCI) +static struct imx_pcie_priv imx_pcie_priv = { + .dbi_base = (void __iomem *)MX6_DBI_ADDR, + .cfg_base = (void __iomem *)MX6_ROOT_ADDR, +}; + +static struct imx_pcie_priv *priv = &imx_pcie_priv; + +static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, + int where, u32 *val) +{ + struct imx_pcie_priv *priv = hose->priv_data; + + return imx_pcie_read_cfg(priv, d, where, val); +} + +static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, + int where, u32 val) +{ + struct imx_pcie_priv *priv = hose->priv_data; + + return imx_pcie_write_cfg(priv, d, where, val); +} + void imx_pcie_init(void) { /* Static instance of the controller. */ @@ -665,6 +700,8 @@ void imx_pcie_init(void) memset(&pcc, 0, sizeof(pcc)); + hose->priv_data = priv; + /* PCI I/O space */ pci_set_region(&hose->regions[0], MX6_IO_ADDR, MX6_IO_ADDR, @@ -691,7 +728,7 @@ void imx_pcie_init(void) imx_pcie_write_config); /* Start the controller. */ - ret = imx_pcie_link_up(); + ret = imx_pcie_link_up(priv); if (!ret) { pci_register_hose(hose); @@ -701,7 +738,7 @@ void imx_pcie_init(void) void imx_pcie_remove(void) { - imx6_pcie_assert_core_reset(true); + imx6_pcie_assert_core_reset(priv, true); } /* Probe function. */ @@ -709,3 +746,86 @@ void pci_init_board(void) { imx_pcie_init(); } +#else +static int imx_pcie_dm_read_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong *value, + enum pci_size_t size) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + u32 tmpval; + int ret; + + ret = imx_pcie_read_cfg(priv, bdf, offset, &tmpval); + if (ret) + return ret; + + *value = pci_conv_32_to_size(tmpval, offset, size); + return 0; +} + +static int imx_pcie_dm_write_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + u32 tmpval, newval; + int ret; + + ret = imx_pcie_read_cfg(priv, bdf, offset, &tmpval); + if (ret) + return ret; + + newval = pci_conv_size_to_32(tmpval, value, offset, size); + return imx_pcie_write_cfg(priv, bdf, offset, newval); +} + +static int imx_pcie_dm_probe(struct udevice *dev) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + + return imx_pcie_link_up(priv); +} + +static int imx_pcie_dm_remove(struct udevice *dev) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + + imx6_pcie_assert_core_reset(priv, true); + + return 0; +} + +static int imx_pcie_ofdata_to_platdata(struct udevice *dev) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + + priv->dbi_base = (void __iomem *)devfdt_get_addr_index(dev, 0); + priv->cfg_base = (void __iomem *)devfdt_get_addr_index(dev, 1); + if (!priv->dbi_base || !priv->cfg_base) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops imx_pcie_ops = { + .read_config = imx_pcie_dm_read_config, + .write_config = imx_pcie_dm_write_config, +}; + +static const struct udevice_id imx_pcie_ids[] = { + { .compatible = "fsl,imx6q-pcie" }, + { } +}; + +U_BOOT_DRIVER(imx_pcie) = { + .name = "imx_pcie", + .id = UCLASS_PCI, + .of_match = imx_pcie_ids, + .ops = &imx_pcie_ops, + .probe = imx_pcie_dm_probe, + .remove = imx_pcie_dm_remove, + .ofdata_to_platdata = imx_pcie_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct imx_pcie_priv), + .flags = DM_FLAG_OS_PREPARE, +}; +#endif diff --git a/drivers/pinctrl/nxp/pinctrl-imx6.c b/drivers/pinctrl/nxp/pinctrl-imx6.c index d7c95bb738..0c1e7a9c05 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx6.c +++ b/drivers/pinctrl/nxp/pinctrl-imx6.c @@ -10,7 +10,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx6_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx6_pinctrl_soc_info __section(".data"); /* FIXME Before reloaction, BSS is overlapped with DT area */ static struct imx_pinctrl_soc_info imx6ul_pinctrl_soc_info = { diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index b0cd260354..450935fdc1 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -48,6 +48,13 @@ config PMIC_AS3722 interface and is designs to cover most of the power managementment required for a tablets or laptop. +config DM_PMIC_BD71837 + bool "Enable Driver Model for PMIC BD71837" + 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/Makefile b/drivers/power/pmic/Makefile index ce250cb155..888dbb2857 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_DM_PMIC_FAN53555) += fan53555.o obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o +obj-$(CONFIG_$(SPL_)DM_PMIC_BD71837) += bd71837.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o diff --git a/drivers/power/pmic/bd71837.c b/drivers/power/pmic/bd71837.c new file mode 100644 index 0000000000..24d9f7fab7 --- /dev/null +++ b/drivers/power/pmic/bd71837.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/bd71837.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct pmic_child_info pmic_children_info[] = { + /* buck */ + { .prefix = "b", .driver = BD71837_REGULATOR_DRIVER}, + /* ldo */ + { .prefix = "l", .driver = BD71837_REGULATOR_DRIVER}, + { }, +}; + +static int bd71837_reg_count(struct udevice *dev) +{ + return BD71837_REG_NUM; +} + +static int bd71837_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + pr_err("write error to device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int bd71837_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + pr_err("read error from device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int bd71837_bind(struct udevice *dev) +{ + int children; + ofnode regulators_node; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found!", __func__, + dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} + +static struct dm_pmic_ops bd71837_ops = { + .reg_count = bd71837_reg_count, + .read = bd71837_read, + .write = bd71837_write, +}; + +static const struct udevice_id bd71837_ids[] = { + { .compatible = "rohm,bd71837", .data = 0x4b, }, + { } +}; + +U_BOOT_DRIVER(pmic_bd71837) = { + .name = "bd71837 pmic", + .id = UCLASS_PMIC, + .of_match = bd71837_ids, + .bind = bd71837_bind, + .ops = &bd71837_ops, +}; diff --git a/drivers/power/regulator/pfuze100.c b/drivers/power/regulator/pfuze100.c index 99073d6018..d6d35f3a39 100644 --- a/drivers/power/regulator/pfuze100.c +++ b/drivers/power/regulator/pfuze100.c @@ -482,11 +482,11 @@ static int pfuze100_regulator_val(struct udevice *dev, int op, int *uV) debug("Set voltage for REGULATOR_TYPE_FIXED regulator\n"); return -EINVAL; } else if (desc->volt_table) { - for (i = 0; i < desc->vsel_mask; i++) { + for (i = 0; i <= desc->vsel_mask; i++) { if (*uV == desc->volt_table[i]) break; } - if (i == desc->vsel_mask) { + if (i == desc->vsel_mask + 1) { debug("Unsupported voltage %u\n", *uV); return -EINVAL; } diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index 476df25805..a435e68005 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -342,6 +342,7 @@ static int mxc_serial_ofdata_to_platdata(struct udevice *dev) } static const struct udevice_id mxc_serial_ids[] = { + { .compatible = "fsl,imx6sx-uart" }, { .compatible = "fsl,imx6ul-uart" }, { .compatible = "fsl,imx7d-uart" }, { .compatible = "fsl,imx6q-uart" }, diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index 6846762719..d94aaf9fdb 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -38,6 +38,8 @@ __weak int board_spi_cs_gpio(unsigned bus, unsigned cs) #define CONFIG_SYS_SPI_MXC_WAIT (CONFIG_SYS_HZ/100) /* 10 ms */ #endif +#define MAX_CS_COUNT 4 + struct mxc_spi_slave { struct spi_slave slave; unsigned long base; @@ -50,6 +52,8 @@ struct mxc_spi_slave { unsigned int max_hz; unsigned int mode; struct gpio_desc ss; + struct gpio_desc cs_gpios[MAX_CS_COUNT]; + struct udevice *dev; }; static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave) @@ -59,22 +63,38 @@ static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave) static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs) { - if (CONFIG_IS_ENABLED(DM_SPI)) { - dm_gpio_set_value(&mxcs->ss, 1); - } else { - if (mxcs->gpio > 0) - gpio_set_value(mxcs->gpio, mxcs->ss_pol); - } +#if defined(CONFIG_DM_SPI) + struct udevice *dev = mxcs->dev; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + + u32 cs = slave_plat->cs; + + if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs])) + return; + + dm_gpio_set_value(&mxcs->cs_gpios[cs], 1); +#else + if (mxcs->gpio > 0) + gpio_set_value(mxcs->gpio, mxcs->ss_pol); +#endif } static void mxc_spi_cs_deactivate(struct mxc_spi_slave *mxcs) { - if (CONFIG_IS_ENABLED(DM_SPI)) { - dm_gpio_set_value(&mxcs->ss, 0); - } else { - if (mxcs->gpio > 0) - gpio_set_value(mxcs->gpio, !(mxcs->ss_pol)); - } +#if defined(CONFIG_DM_SPI) + struct udevice *dev = mxcs->dev; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + + u32 cs = slave_plat->cs; + + if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs])) + return; + + dm_gpio_set_value(&mxcs->cs_gpios[cs], 0); +#else + if (mxcs->gpio > 0) + gpio_set_value(mxcs->gpio, !(mxcs->ss_pol)); +#endif } u32 get_cspi_div(u32 div) @@ -488,28 +508,35 @@ void spi_release_bus(struct spi_slave *slave) static int mxc_spi_probe(struct udevice *bus) { - struct mxc_spi_slave *plat = bus->platdata; struct mxc_spi_slave *mxcs = dev_get_platdata(bus); int node = dev_of_offset(bus); const void *blob = gd->fdt_blob; int ret; + int i; - if (gpio_request_by_name(bus, "cs-gpios", 0, &plat->ss, - GPIOD_IS_OUT)) { - dev_err(bus, "No cs-gpios property\n"); - return -EINVAL; + ret = gpio_request_list_by_name(bus, "cs-gpios", mxcs->cs_gpios, + ARRAY_SIZE(mxcs->cs_gpios), 0); + if (ret < 0) { + pr_err("Can't get %s gpios! Error: %d", bus->name, ret); + return ret; } - plat->base = devfdt_get_addr(bus); - if (plat->base == FDT_ADDR_T_NONE) - return -ENODEV; + for (i = 0; i < ARRAY_SIZE(mxcs->cs_gpios); i++) { + if (!dm_gpio_is_valid(&mxcs->cs_gpios[i])) + continue; - ret = dm_gpio_set_value(&plat->ss, 0); - if (ret) { - dev_err(bus, "Setting cs error\n"); - return ret; + ret = dm_gpio_set_dir_flags(&mxcs->cs_gpios[i], + GPIOD_IS_OUT | GPIOD_ACTIVE_LOW); + if (ret) { + dev_err(bus, "Setting cs %d error\n", i); + return ret; + } } + mxcs->base = devfdt_get_addr(bus); + if (mxcs->base == FDT_ADDR_T_NONE) + return -ENODEV; + mxcs->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 20000000); @@ -530,6 +557,8 @@ static int mxc_spi_claim_bus(struct udevice *dev) struct mxc_spi_slave *mxcs = dev_get_platdata(dev->parent); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + mxcs->dev = dev; + return mxc_spi_claim_bus_internal(mxcs, slave_plat->cs); } |