diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-11 13:43:00 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-11 13:43:00 +0200 |
commit | 3fcf4400a7b051bdbe9fc175b88336519099ff22 (patch) | |
tree | 59e47312f23697970b3defc010a15f367b8e5082 /drivers | |
parent | b33c2913d747d3c55019a1d310427ca2697de6fc (diff) | |
parent | 22a073e3a9cdbc8034d5c58a6840e2567e5b3ddd (diff) | |
download | barebox-3fcf4400a7b051bdbe9fc175b88336519099ff22.tar.gz barebox-3fcf4400a7b051bdbe9fc175b88336519099ff22.tar.xz |
Merge branch 'for-next/imx'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ddr/imx8m/ddr_init.c | 33 | ||||
-rw-r--r-- | drivers/ddr/imx8m/ddrphy_train.c | 74 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-imx-early.c | 21 | ||||
-rw-r--r-- | drivers/mci/imx-esdhc-pbl.c | 2 | ||||
-rw-r--r-- | drivers/net/fec_imx.c | 11 | ||||
-rw-r--r-- | drivers/phy/phy-core.c | 11 | ||||
-rw-r--r-- | drivers/usb/imx/chipidea-imx.c | 10 | ||||
-rw-r--r-- | drivers/watchdog/imxwd.c | 18 |
8 files changed, 114 insertions, 66 deletions
diff --git a/drivers/ddr/imx8m/ddr_init.c b/drivers/ddr/imx8m/ddr_init.c index 9a4b4e2ca8..18969ddb53 100644 --- a/drivers/ddr/imx8m/ddr_init.c +++ b/drivers/ddr/imx8m/ddr_init.c @@ -49,17 +49,18 @@ static void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num) */ #define IMX8M_SAVED_DRAM_TIMING_BASE 0x180000 -static int imx8m_ddr_init(struct dram_timing_info *dram_timing, - enum ddrc_type type) +int imx8m_ddr_init(struct dram_timing_info *dram_timing, + unsigned type) { unsigned long src_ddrc_rcr = MX8M_SRC_DDRC_RCR_ADDR; unsigned int tmp, initial_drate, target_freq; + enum ddrc_type ddrc_type = get_ddrc_type(type); int ret; pr_debug("start DRAM init\n"); /* Step1: Follow the power up procedure */ - switch (type) { + switch (ddrc_type) { case DDRC_TYPE_MQ: reg32_write(src_ddrc_rcr + 0x04, 0x8f00000f); reg32_write(src_ddrc_rcr, 0x8f00000f); @@ -81,7 +82,7 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing, initial_drate = dram_timing->fsp_msg[0].drate; /* default to the frequency point 0 clock */ - ddrphy_init_set_dfi_clk(initial_drate, type); + ddrphy_init_set_dfi_clk(initial_drate, ddrc_type); /* D-aasert the presetn */ reg32_write(src_ddrc_rcr, 0x8F000006); @@ -107,7 +108,7 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing, /* if ddr type is LPDDR4, do it */ tmp = reg32_read(DDRC_MSTR(0)); - if (tmp & (0x1 << 5) && type != DDRC_TYPE_MN) + if (tmp & (0x1 << 5) && ddrc_type != DDRC_TYPE_MN) reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */ /* determine the initial boot frequency */ @@ -154,7 +155,7 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing, reg32_write(DDRC_SWCTL(0), 0x00000000); /* Apply rank-to-rank workaround */ - update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, type); + update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, ddrc_type); /* Step16: Set DFIMISC.dfi_init_start to 1 */ setbits_le32(DDRC_DFIMISC(0), (0x1 << 5)); @@ -210,23 +211,3 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing, return 0; } - -int imx8mm_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM); -} - -int imx8mn_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN); -} - -int imx8mq_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ); -} - -int imx8mp_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP); -} diff --git a/drivers/ddr/imx8m/ddrphy_train.c b/drivers/ddr/imx8m/ddrphy_train.c index 9dc20a4762..e9d35afdfb 100644 --- a/drivers/ddr/imx8m/ddrphy_train.c +++ b/drivers/ddr/imx8m/ddrphy_train.c @@ -11,6 +11,48 @@ #include <firmware.h> #include <mach/imx8m-regs.h> +static const u16 *lpddr4_imem_1d; +static size_t lpddr4_imem_1d_size; +static const u16 *lpddr4_dmem_1d; +static size_t lpddr4_dmem_1d_size; +static const u16 *lpddr4_imem_2d; +static size_t lpddr4_imem_2d_size; +static const u16 *lpddr4_dmem_2d; +static size_t lpddr4_dmem_2d_size; + +void ddr_get_firmware_lpddr4(void) +{ + get_builtin_firmware(lpddr4_pmu_train_1d_imem_bin, &lpddr4_imem_1d, + &lpddr4_imem_1d_size); + get_builtin_firmware(lpddr4_pmu_train_1d_dmem_bin, &lpddr4_dmem_1d, + &lpddr4_dmem_1d_size); + get_builtin_firmware(lpddr4_pmu_train_2d_imem_bin, &lpddr4_imem_2d, + &lpddr4_imem_2d_size); + get_builtin_firmware(lpddr4_pmu_train_2d_dmem_bin, &lpddr4_dmem_2d, + &lpddr4_dmem_2d_size); +} + +static const u16 *ddr4_imem_1d; +static size_t ddr4_imem_1d_size; +static const u16 *ddr4_dmem_1d; +static size_t ddr4_dmem_1d_size; +static const u16 *ddr4_imem_2d; +static size_t ddr4_imem_2d_size; +static const u16 *ddr4_dmem_2d; +static size_t ddr4_dmem_2d_size; + +void ddr_get_firmware_ddr(void) +{ + get_builtin_firmware(ddr4_imem_1d_bin, &ddr4_imem_1d, + &ddr4_imem_1d_size); + get_builtin_firmware(ddr4_dmem_1d_bin, &ddr4_dmem_1d, + &ddr4_dmem_1d_size); + get_builtin_firmware(ddr4_imem_2d_bin, &ddr4_imem_2d, + &ddr4_imem_2d_size); + get_builtin_firmware(ddr4_dmem_2d_bin, &ddr4_dmem_2d, + &ddr4_dmem_2d_size); +} + void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type) { const u16 *imem, *dmem; @@ -18,19 +60,27 @@ void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type) if (dram_is_lpddr4(dram_type)) { if (fw_type == FW_1D_IMAGE) { - get_builtin_firmware(lpddr4_pmu_train_1d_imem_bin, &imem, &isize); - get_builtin_firmware(lpddr4_pmu_train_1d_dmem_bin, &dmem, &dsize); + imem = lpddr4_imem_1d; + isize = lpddr4_imem_1d_size; + dmem = lpddr4_dmem_1d; + dsize = lpddr4_dmem_1d_size; } else { - get_builtin_firmware(lpddr4_pmu_train_2d_imem_bin, &imem, &isize); - get_builtin_firmware(lpddr4_pmu_train_2d_dmem_bin, &dmem, &dsize); + imem = lpddr4_imem_2d; + isize = lpddr4_imem_2d_size; + dmem = lpddr4_dmem_2d; + dsize = lpddr4_dmem_2d_size; } } else if (dram_is_ddr4(dram_type)) { if (fw_type == FW_1D_IMAGE) { - get_builtin_firmware(ddr4_imem_1d_bin, &imem, &isize); - get_builtin_firmware(ddr4_dmem_1d_bin, &dmem, &dsize); + imem = ddr4_imem_1d; + isize = ddr4_imem_1d_size; + dmem = ddr4_dmem_1d; + dsize = ddr4_dmem_1d_size; } else { - get_builtin_firmware(ddr4_imem_2d_bin, &imem, &isize); - get_builtin_firmware(ddr4_dmem_2d_bin, &dmem, &dsize); + imem = ddr4_imem_2d; + isize = ddr4_imem_2d_size; + dmem = ddr4_dmem_2d; + dsize = ddr4_dmem_2d_size; } } else { panic("No matching DDR PHY firmware found"); @@ -43,8 +93,10 @@ void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type) DDRC_PHY_DMEM, dmem, dsize); } -int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type) +int ddr_cfg_phy(struct dram_timing_info *dram_timing, unsigned type) { + enum ddrc_type ddrc_type = get_ddrc_type(type); + enum dram_type dram_type = get_dram_type(type); struct dram_cfg_param *dram_cfg; struct dram_fsp_msg *fsp_msg; unsigned int num; @@ -66,11 +118,11 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type) for (i = 0; i < dram_timing->fsp_msg_num; i++) { pr_debug("DRAM PHY training for %dMTS\n", fsp_msg->drate); /* set dram PHY input clocks to desired frequency */ - ddrphy_init_set_dfi_clk(fsp_msg->drate, type); + ddrphy_init_set_dfi_clk(fsp_msg->drate, ddrc_type); /* load the dram training firmware image */ dwc_ddrphy_apb_wr(0xd0000, 0x0); - ddr_load_train_code(dram_timing->dram_type, fsp_msg->fw_type); + ddr_load_train_code(dram_type, fsp_msg->fw_type); /* load the frequency set point message block parameter */ dram_cfg = fsp_msg->fsp_cfg; diff --git a/drivers/i2c/busses/i2c-imx-early.c b/drivers/i2c/busses/i2c-imx-early.c index a79d7bd88c..4e0f7e517d 100644 --- a/drivers/i2c/busses/i2c-imx-early.c +++ b/drivers/i2c/busses/i2c-imx-early.c @@ -9,11 +9,12 @@ */ #include <common.h> #include <i2c/i2c.h> -#include <i2c/i2c-early.h> +#include <pbl/i2c.h> #include "i2c-imx.h" struct fsl_i2c { + struct pbl_i2c i2c; void __iomem *regs; unsigned int i2cr_ien_opcode; unsigned int i2sr_clr_opcode; @@ -170,7 +171,7 @@ static int i2c_fsl_write(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg) /* write data */ for (i = 0; i < msg->len; i++) { ret = i2c_fsl_send(fsl_i2c, msg->buf[i]); - if (ret) + if (ret) return ret; } @@ -229,9 +230,9 @@ static int i2c_fsl_read(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg) * If successful returns the number of messages transferred, otherwise a negative * error code is returned. */ -int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num) +static int i2c_fsl_xfer(struct pbl_i2c *i2c, struct i2c_msg *msgs, int num) { - struct fsl_i2c *fsl_i2c = ctx; + struct fsl_i2c *fsl_i2c = container_of(i2c, struct fsl_i2c, i2c); unsigned int i, temp; int ret; @@ -288,7 +289,7 @@ static struct fsl_i2c fsl_i2c; * This function returns a context pointer suitable to transfer I2C messages * using i2c_fsl_xfer. */ -void *ls1046_i2c_init(void __iomem *regs) +struct pbl_i2c *ls1046_i2c_init(void __iomem *regs) { fsl_i2c.regs = regs; fsl_i2c.regshift = 0; @@ -297,10 +298,12 @@ void *ls1046_i2c_init(void __iomem *regs) /* Divider for ~100kHz when coming from the ROM */ fsl_i2c.ifdr = 0x3e; - return &fsl_i2c; + fsl_i2c.i2c.xfer = i2c_fsl_xfer; + + return &fsl_i2c.i2c; } -void *imx8m_i2c_early_init(void __iomem *regs) +struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs) { fsl_i2c.regs = regs; fsl_i2c.regshift = 2; @@ -309,5 +312,7 @@ void *imx8m_i2c_early_init(void __iomem *regs) /* Divider for ~100kHz when coming from the ROM */ fsl_i2c.ifdr = 0x0f; - return &fsl_i2c; + fsl_i2c.i2c.xfer = i2c_fsl_xfer; + + return &fsl_i2c.i2c; } diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c index 5a76e7a663..c81eba5b9d 100644 --- a/drivers/mci/imx-esdhc-pbl.c +++ b/drivers/mci/imx-esdhc-pbl.c @@ -44,7 +44,7 @@ static int esdhc_send_ext_csd(struct fsl_esdhc_host *host) return esdhc_send_cmd(host, &cmd, &data); } -static bool esdhc_bootpart_active(struct fsl_esdhc_host *host) +static bool __maybe_unused esdhc_bootpart_active(struct fsl_esdhc_host *host) { unsigned bootpart; diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 0c2d600d12..673555a48a 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -320,6 +320,10 @@ static int fec_init(struct eth_device *dev) /* size of each buffer */ writel(FEC_MAX_PKT_SIZE, fec->regs + FEC_EMRBR); + /* set rx and tx buffer descriptor base address */ + writel(virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR); + writel(virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR); + return 0; } @@ -359,6 +363,8 @@ static int fec_open(struct eth_device *edev) if (fec->phy_init) fec->phy_init(edev->phydev); + fec_init(edev); + /* * Initialize RxBD/TxBD rings */ @@ -839,9 +845,6 @@ static int fec_probe(struct device_d *dev) base += FEC_RBD_NUM * sizeof(struct buffer_descriptor); fec->tbd_base = base; - writel(virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR); - writel(virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR); - ret = fec_alloc_receive_packets(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE); if (ret < 0) goto free_xbd; @@ -861,8 +864,6 @@ static int fec_probe(struct device_d *dev) if (ret) goto free_receive_packets; - fec_init(edev); - fec->miibus.read = fec_miibus_read; fec->miibus.write = fec_miibus_write; diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index b298da0000..8a57bd1aa9 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -220,6 +220,11 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node) { struct phy_provider *phy_provider; struct device_node *child; + int ret; + + ret = of_device_ensure_probed(node); + if (ret) + return ERR_PTR(ret); list_for_each_entry(phy_provider, &phy_provider_list, list) { if (phy_provider->dev->device_node == node) @@ -255,10 +260,6 @@ static struct phy *_of_phy_get(struct device_node *np, int index) if (ret) return ERR_PTR(-ENODEV); - ret = of_device_ensure_probed(args.np); - if (ret) - return ERR_PTR(ret); - phy_provider = of_phy_provider_lookup(args.np); if (IS_ERR(phy_provider)) { return ERR_CAST(phy_provider); @@ -316,7 +317,7 @@ struct phy *of_phy_get_by_phandle(struct device_d *dev, const char *phandle, phy_provider = of_phy_provider_lookup(np); if (IS_ERR(phy_provider)) { - return ERR_PTR(-ENODEV); + return ERR_CAST(phy_provider); } return phy_provider->of_xlate(phy_provider->dev, NULL); diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c index bf8b6f1eb8..f71cf80b7d 100644 --- a/drivers/usb/imx/chipidea-imx.c +++ b/drivers/usb/imx/chipidea-imx.c @@ -260,8 +260,6 @@ static int imx_chipidea_probe(struct device_d *dev) * devices which have only one. */ ci->clk = clk_get(dev, NULL); - if (!IS_ERR(ci->clk)) - clk_enable(ci->clk); /* Device trees are using both "phys" and "fsl,usbphy". Prefer the * more modern former one but fall back to the old one. @@ -302,6 +300,14 @@ static int imx_chipidea_probe(struct device_d *dev) ci->data.drvdata = ci; ci->data.usbphy = ci->usbphy; + /* + * Enable the clock after we ensured that all resources are available. + * This is crucial since the phy can be missing which and so the + * usb-controller <-> usb-phy communication is only partly initialized. + * This can trigger strange system hangs at least on i.MX8M SoCs. + */ + clk_enable(ci->clk); + if ((ci->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_HSIC) imx_chipidea_port_init(ci); diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c index 31ea388c2c..dba92cb46a 100644 --- a/drivers/watchdog/imxwd.c +++ b/drivers/watchdog/imxwd.c @@ -239,18 +239,17 @@ static int imx_wd_probe(struct device_d *dev) priv = xzalloc(sizeof(struct imx_wd)); iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) { - dev_err(dev, "could not get memory region\n"); - return PTR_ERR(iores); - } + if (IS_ERR(iores)) + return dev_err_probe(dev, PTR_ERR(iores), + "could not get memory region\n"); clk = clk_get(dev, NULL); if (IS_ERR(clk)) - return PTR_ERR(clk); + return dev_err_probe(dev, PTR_ERR(clk), "Failed to get clk\n"); ret = clk_enable(clk); if (ret) - return ret; + return dev_err_probe(dev, ret, "Failed to enable clk\n"); priv->base = IOMEM(iores->start); priv->ops = ops; @@ -272,14 +271,17 @@ static int imx_wd_probe(struct device_d *dev) } ret = watchdog_register(&priv->wd); - if (ret) + if (ret) { + dev_err_probe(dev, ret, "Failed to register watchdog device\n"); goto on_error; + } } if (priv->ops->init) { ret = priv->ops->init(priv); if (ret) { - dev_err(dev, "Failed to init watchdog device %d\n", ret); + dev_err_probe(dev, ret, + "Failed to init watchdog device\n"); goto error_unregister; } } |