diff options
author | Tom Rini <trini@konsulko.com> | 2021-11-11 17:04:20 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-11-11 17:04:20 +0300 |
commit | 1e72ad6b387c599f477f83cda67ab525c089a9b0 (patch) | |
tree | e9902c9fb94534a8c98d880db36a74a8ec17e173 /drivers | |
parent | 166a77b34b30f64f7b12a3016b0bba49d568c52e (diff) | |
parent | 99e1fa89f1a6ce13787af34cbd933c846bc7e93a (diff) | |
download | u-boot-1e72ad6b387c599f477f83cda67ab525c089a9b0.tar.xz |
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
- device-tree sync-up with Linux for ls1028a
- fixes/update in fsl-ddr driver, fsl-validate, lx2162a, fsl-mc,
spintable code, configs, qspi node, pci
- enable EFI_SET_TIME support in sl28
- powerpc: Drop -mstring
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/sata_ceva.c | 2 | ||||
-rw-r--r-- | drivers/crypto/fsl/fsl_hash.c | 14 | ||||
-rw-r--r-- | drivers/ddr/fsl/fsl_ddr_gen4.c | 14 | ||||
-rw-r--r-- | drivers/ddr/fsl/lc_common_dimm_params.c | 10 | ||||
-rw-r--r-- | drivers/ddr/fsl/main.c | 11 | ||||
-rw-r--r-- | drivers/ddr/fsl/util.c | 12 | ||||
-rw-r--r-- | drivers/net/Kconfig | 10 | ||||
-rw-r--r-- | drivers/net/fsl-mc/mc.c | 89 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape_fixup.c | 8 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape_fixup_common.c | 6 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape_gen4.c | 4 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape_gen4_fixup.c | 5 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape_rc.c | 64 | ||||
-rw-r--r-- | drivers/qe/Kconfig | 4 | ||||
-rw-r--r-- | drivers/serial/serial_lpuart.c | 2 | ||||
-rw-r--r-- | drivers/spi/fsl_dspi.c | 6 | ||||
-rw-r--r-- | drivers/usb/common/common.c | 4 | ||||
-rw-r--r-- | drivers/usb/dwc3/Kconfig | 10 | ||||
-rw-r--r-- | drivers/usb/dwc3/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.c | 95 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 22 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-layerscape.c | 222 | ||||
-rw-r--r-- | drivers/usb/host/xhci-fsl.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/sp805_wdt.c | 2 |
24 files changed, 566 insertions, 52 deletions
diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c index 87e6a90f74..b71f10223d 100644 --- a/drivers/ata/sata_ceva.c +++ b/drivers/ata/sata_ceva.c @@ -212,7 +212,7 @@ static int sata_ceva_of_to_plat(struct udevice *dev) if (priv->base == FDT_ADDR_T_NONE) return -EINVAL; - ret = dev_read_resource_byname(dev, "ecc-addr", &res_regs); + ret = dev_read_resource_byname(dev, "sata-ecc", &res_regs); if (ret) priv->ecc_base = 0; else diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c index 8b5c26db07..8039473012 100644 --- a/drivers/crypto/fsl/fsl_hash.c +++ b/drivers/crypto/fsl/fsl_hash.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2014 Freescale Semiconductor, Inc. - * + * Copyright 2021 NXP */ #include <common.h> @@ -120,8 +120,8 @@ static int caam_hash_update(void *hash_ctx, const void *buf, * Perform progressive hashing on the given buffer and copy hash at * destination buffer * - * The context is freed after completion of hash operation. - * + * The context is freed after successful completion of hash operation. + * In case of failure, context is not freed. * @hash_ctx: Pointer to the context for hashing * @dest_buf: Pointer to the destination buffer where hash is to be copied * @size: Size of the buffer being hashed @@ -136,7 +136,6 @@ static int caam_hash_finish(void *hash_ctx, void *dest_buf, int i = 0, ret = 0; if (size < driver_hash[caam_algo].digestsize) { - free(ctx); return -EINVAL; } @@ -152,11 +151,12 @@ static int caam_hash_finish(void *hash_ctx, void *dest_buf, ret = run_descriptor_jr(ctx->sha_desc); - if (ret) + if (ret) { debug("Error %x\n", ret); - else + return ret; + } else { memcpy(dest_buf, ctx->hash, sizeof(ctx->hash)); - + } free(ctx); return ret; } diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index e43c680154..89cb4d352e 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2014-2020 Freescale Semiconductor, Inc. + * Copyright 2021 NXP */ #include <common.h> @@ -57,7 +58,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, struct ccsr_ddr __iomem *ddr; u32 temp32; u32 total_gb_size_per_controller; - int timeout; + int timeout = 0; + int ddr_freq_for_timeout = 0; int mod_bnds = 0; #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 @@ -511,8 +513,14 @@ step2: */ bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) >> SDRAM_CFG_DBW_SHIFT); - timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / - (get_ddr_freq(ctrl_num) >> 20)) << 2; + ddr_freq_for_timeout = (get_ddr_freq(ctrl_num) >> 20) << 2; + if (ddr_freq_for_timeout) { + timeout = ((total_gb_size_per_controller << + (6 - bus_width)) * 100 / + ddr_freq_for_timeout); + } else { + debug("Error in getting timeout.\n"); + } total_gb_size_per_controller >>= 4; /* shift down to gb size */ debug("total %d GB\n", total_gb_size_per_controller); debug("Need to wait up to %d * 10ms\n", timeout); diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c index d299d763db..d738ae3a7c 100644 --- a/drivers/ddr/fsl/lc_common_dimm_params.c +++ b/drivers/ddr/fsl/lc_common_dimm_params.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright 2008-2016 Freescale Semiconductor, Inc. - * Copyright 2017-2018 NXP Semiconductor + * Copyright 2017-2021 NXP Semiconductor */ #include <common.h> @@ -23,7 +23,7 @@ compute_cas_latency(const unsigned int ctrl_num, unsigned int caslat_actual; unsigned int retry = 16; unsigned int tmp = ~0; - const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); + unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); #ifdef CONFIG_SYS_FSL_DDR3 const unsigned int taamax = 20000; #else @@ -37,6 +37,12 @@ compute_cas_latency(const unsigned int ctrl_num, } common_caslat = tmp; + if (!mclk_ps) { + printf("DDR clock (MCLK cycle was 0 ps), So setting it to slowest DIMM(s) (tCKmin %u ps).\n", + outpdimm->tckmin_x_ps); + mclk_ps = outpdimm->tckmin_x_ps; + } + /* validate if the memory clk is in the range of dimms */ if (mclk_ps < outpdimm->tckmin_x_ps) { printf("DDR clock (MCLK cycle %u ps) is faster than " diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 8e147160b9..f389e5ef95 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2021 NXP */ /* @@ -297,9 +298,13 @@ const char * step_to_string(unsigned int step) { unsigned int s = __ilog2(step); - if ((1 << s) != step) - return step_string_tbl[7]; - + if (s <= 31) { + if ((1 << s) != step) + return step_string_tbl[7]; + } else { + if ((1 << (s - 32)) != step) + return step_string_tbl[7]; + } if (s >= ARRAY_SIZE(step_string_tbl)) { printf("Error for the step in %s\n", __func__); s = 0; diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index ac4f8d2732..43cb01804b 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2021 NXP */ #include <common.h> @@ -75,10 +76,13 @@ unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num) /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ unsigned long long rem, mclk_ps = ULL_2E12; - - /* Now perform the big divide, the result fits in 32-bits */ - rem = do_div(mclk_ps, data_rate); - result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; + if (data_rate) { + /* Now perform the big divide, the result fits in 32-bits */ + rem = do_div(mclk_ps, data_rate); + result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; + } else { + result = 0; + } return result; } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6c12959f37..3f12b758be 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -344,6 +344,16 @@ config FMAN_ENET help This driver support the Freescale FMan Ethernet controller +config SYS_FMAN_FW_ADDR + hex "FMAN Firmware Address" + depends on FMAN_ENET + default 0x0 + +config SYS_QE_FMAN_FW_LENGTH + hex "FMAN QE Firmware length" + depends on FMAN_ENET || QE || U_QE + default 0x10000 + config FTMAC100 bool "Ftmac100 Ethernet Support" help diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index d52c986d4b..bc1c31d467 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -11,6 +11,7 @@ #include <image.h> #include <log.h> #include <malloc.h> +#include <mapmem.h> #include <asm/global_data.h> #include <linux/bug.h> #include <asm/io.h> @@ -38,6 +39,16 @@ #define MC_BOOT_ENV_VAR "mcinitcmd" #define MC_DRAM_BLOCK_DEFAULT_SIZE (512UL * 1024 * 1024) +#define MC_BUFFER_SIZE (1024 * 1024 * 16) +#define MAGIC_MC 0x4d430100 +#define MC_FW_ADDR_MASK_LOW 0xE0000000 +#define MC_FW_ADDR_MASK_HIGH 0X1FFFF +#define MC_STRUCT_BUFFER_OFFSET 0x01000000 +#define MC_OFFSET_DELTA MC_STRUCT_BUFFER_OFFSET + +#define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x80000000 +#define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND)) + DECLARE_GLOBAL_DATA_PTR; static int mc_memset_resv_ram; static struct mc_version mc_ver_info; @@ -1773,11 +1784,78 @@ err: return err; } +static void print_k_bytes(const void *buf, ssize_t *size) +{ + while (*size > 0) { + int count = printf("%s", (char *)buf); + + buf += count; + *size -= count; + } +} + +static void mc_dump_log(void) +{ + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; + u64 high = in_le64(&mc_ccsr_regs->reg_mcfbahr) & MC_FW_ADDR_MASK_HIGH; + u64 low = in_le64(&mc_ccsr_regs->reg_mcfbalr) & MC_FW_ADDR_MASK_LOW; + u32 buf_len, wrapped, last_byte, magic, buf_start; + u64 mc_addr = (high << 32) | low; + struct log_header *header; + ssize_t size, bytes_end; + const void *end_of_data; + const void *map_addr; + const void *end_addr; + const void *cur_ptr; + const void *buf; + + map_addr = map_sysmem(mc_addr + MC_STRUCT_BUFFER_OFFSET, + MC_BUFFER_SIZE); + header = (struct log_header *)map_addr; + last_byte = in_le32(&header->last_byte); + buf_len = in_le32(&header->buf_length); + magic = in_le32(&header->magic_word); + buf_start = in_le32(&header->buf_start); + buf = map_addr + buf_start - MC_OFFSET_DELTA; + end_addr = buf + buf_len; + wrapped = last_byte & LOG_HEADER_FLAG_BUFFER_WRAPAROUND; + end_of_data = buf + LAST_BYTE(last_byte); + + if (magic != MAGIC_MC) { + puts("Magic number is not valid\n"); + printf("expected = %08x, received = %08x\n", MAGIC_MC, magic); + goto err_magic; + } + + if (wrapped && end_of_data != end_addr) + cur_ptr = end_of_data + 1; + else + cur_ptr = buf; + + if (cur_ptr <= end_of_data) + size = end_of_data - cur_ptr; + else + size = (end_addr - cur_ptr) + (end_of_data - buf); + + bytes_end = end_addr - cur_ptr; + if (size > bytes_end) { + print_k_bytes(cur_ptr, &bytes_end); + + cur_ptr = buf; + size -= bytes_end; + } + + print_k_bytes(buf, &size); + +err_magic: + unmap_sysmem(map_addr); +} + static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int err = 0; - if (argc < 3) + if (argc < 2) goto usage; switch (argv[1][0]) { @@ -1787,6 +1865,8 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET u64 aiop_fw_addr; #endif + if (argc < 3) + goto usage; sub_cmd = argv[2][0]; @@ -1918,6 +1998,12 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, } break; } + case 'd': + if (argc > 2) + goto usage; + + mc_dump_log(); + break; default: printf("Invalid option: %s\n", argv[1]); goto usage; @@ -1936,6 +2022,7 @@ U_BOOT_CMD( "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" "fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n" "fsl_mc start aiop [FW_addr] - Start AIOP\n" + "fsl_mc dump_log - Dump MC Log\n" ); void mc_env_boot(void) diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index a58e7a3892..8a2a0e1f4a 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2017-2020 NXP + * Copyright 2017-2021 NXP * Copyright 2014-2015 Freescale Semiconductor, Inc. * Layerscape PCIe driver */ @@ -24,6 +24,8 @@ #include "pcie_layerscape.h" #include "pcie_layerscape_fixup_common.h" +int next_stream_id; + static int fdt_pcie_get_nodeoffset(void *blob, struct ls_pcie_rc *pcie_rc) { int nodeoffset; @@ -607,6 +609,9 @@ static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc) { ft_pcie_ep_fix(blob, pcie_rc); ft_pcie_rc_fix(blob, pcie_rc); + + pcie_rc->stream_id_cur = 0; + pcie_rc->next_lut_index = 0; } /* Fixup Kernel DT for PCIe */ @@ -618,6 +623,7 @@ void ft_pci_setup_ls(void *blob, struct bd_info *bd) ft_pcie_ls_setup(blob, pcie_rc); #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2) + next_stream_id = FSL_PEX_STREAM_ID_START; fdt_fixup_pcie_ls(blob); #endif } diff --git a/drivers/pci/pcie_layerscape_fixup_common.c b/drivers/pci/pcie_layerscape_fixup_common.c index 3216a20027..faccf6c141 100644 --- a/drivers/pci/pcie_layerscape_fixup_common.c +++ b/drivers/pci/pcie_layerscape_fixup_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2019-2020 NXP + * Copyright 2019-2021 NXP * * PCIe DT fixup for NXP Layerscape SoCs * Author: Wasim Khan <wasim.khan@nxp.com> @@ -15,6 +15,8 @@ #include <fdt_support.h> #include "pcie_layerscape_fixup_common.h" +extern int next_stream_id; + void ft_pci_setup(void *blob, struct bd_info *bd) { #if defined(CONFIG_PCIE_LAYERSCAPE_GEN4) @@ -147,8 +149,6 @@ int pcie_next_streamid(int currentid, int idx) /* returns the next available streamid for pcie, -errno if failed */ int pcie_next_streamid(int currentid, int idx) { - static int next_stream_id = FSL_PEX_STREAM_ID_START; - if (next_stream_id > FSL_PEX_STREAM_ID_END) return -EINVAL; diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c index 255e73181d..6ecdd6af40 100644 --- a/drivers/pci/pcie_layerscape_gen4.c +++ b/drivers/pci/pcie_layerscape_gen4.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR X11 /* - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * PCIe Gen4 driver for NXP Layerscape SoCs * Author: Hou Zhiqiang <Minder.Hou@gmail.com> @@ -305,8 +305,6 @@ static void ls_pcie_g4_setup_ctrl(struct ls_pcie_g4 *pcie) ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val); ls_pcie_g4_setup_wins(pcie); - - pcie->stream_id_cur = 0; } static void ls_pcie_g4_ep_inbound_win_set(struct ls_pcie_g4 *pcie, int pf, diff --git a/drivers/pci/pcie_layerscape_gen4_fixup.c b/drivers/pci/pcie_layerscape_gen4_fixup.c index e9ee15558e..7d11234106 100644 --- a/drivers/pci/pcie_layerscape_gen4_fixup.c +++ b/drivers/pci/pcie_layerscape_gen4_fixup.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR X11 /* - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * PCIe Gen4 driver for NXP Layerscape SoCs * Author: Hou Zhiqiang <Minder.Hou@gmail.com> @@ -223,6 +223,9 @@ static void ft_pcie_layerscape_gen4_setup(void *blob, struct ls_pcie_g4 *pcie) { ft_pcie_rc_layerscape_gen4_fix(blob, pcie); ft_pcie_ep_layerscape_gen4_fix(blob, pcie); + + pcie->stream_id_cur = 0; + pcie->next_lut_index = 0; } /* Fixup Kernel DT for PCIe */ diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c index f50d6ef653..17969e2f23 100644 --- a/drivers/pci/pcie_layerscape_rc.c +++ b/drivers/pci/pcie_layerscape_rc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2020 NXP + * Copyright 2020,2021 NXP * Layerscape PCIe driver */ @@ -21,6 +21,12 @@ DECLARE_GLOBAL_DATA_PTR; +struct ls_pcie_drvdata { + u32 lut_offset; + u32 ctrl_offset; + bool big_endian; +}; + static void ls_pcie_cfg0_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev) { struct ls_pcie *pcie = pcie_rc->pcie; @@ -238,11 +244,11 @@ static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc) ls_pcie_dbi_ro_wr_dis(pcie); ls_pcie_disable_bars(pcie_rc); - pcie_rc->stream_id_cur = 0; } static int ls_pcie_probe(struct udevice *dev) { + const struct ls_pcie_drvdata *drvdata = (void *)dev_get_driver_data(dev); struct ls_pcie_rc *pcie_rc = dev_get_priv(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); @@ -260,8 +266,12 @@ static int ls_pcie_probe(struct udevice *dev) pcie_rc->pcie = pcie; + /* try resource name of the official binding first */ ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "dbi", &pcie_rc->dbi_res); + "regs", &pcie_rc->dbi_res); + if (ret) + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "dbi", &pcie_rc->dbi_res); if (ret) { printf("ls-pcie: resource \"dbi\" not found\n"); return ret; @@ -287,21 +297,29 @@ static int ls_pcie_probe(struct udevice *dev) if (pcie->mode == PCI_HEADER_TYPE_NORMAL) return 0; - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "lut", &pcie_rc->lut_res); - if (!ret) - pcie->lut = map_physmem(pcie_rc->lut_res.start, - fdt_resource_size(&pcie_rc->lut_res), - MAP_NOCACHE); + if (drvdata) { + pcie->lut = pcie->dbi + drvdata->lut_offset; + } else { + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "lut", &pcie_rc->lut_res); + if (!ret) + pcie->lut = map_physmem(pcie_rc->lut_res.start, + fdt_resource_size(&pcie_rc->lut_res), + MAP_NOCACHE); + } - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "ctrl", &pcie_rc->ctrl_res); - if (!ret) - pcie->ctrl = map_physmem(pcie_rc->ctrl_res.start, - fdt_resource_size(&pcie_rc->ctrl_res), - MAP_NOCACHE); - if (!pcie->ctrl) - pcie->ctrl = pcie->lut; + if (drvdata) { + pcie->ctrl = pcie->lut + drvdata->ctrl_offset; + } else { + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "ctrl", &pcie_rc->ctrl_res); + if (!ret) + pcie->ctrl = map_physmem(pcie_rc->ctrl_res.start, + fdt_resource_size(&pcie_rc->ctrl_res), + MAP_NOCACHE); + if (!pcie->ctrl) + pcie->ctrl = pcie->lut; + } if (!pcie->ctrl) { printf("%s: NOT find CTRL\n", dev->name); @@ -343,7 +361,10 @@ static int ls_pcie_probe(struct udevice *dev) pcie_rc->cfg1 = pcie_rc->cfg0 + fdt_resource_size(&pcie_rc->cfg_res) / 2; - pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian"); + if (drvdata) + pcie->big_endian = drvdata->big_endian; + else + pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian"); debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n", dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut, @@ -373,8 +394,15 @@ static const struct dm_pci_ops ls_pcie_ops = { .write_config = ls_pcie_write_config, }; +static const struct ls_pcie_drvdata ls1028a_drvdata = { + .lut_offset = 0x80000, + .ctrl_offset = 0x40000, + .big_endian = false, +}; + static const struct udevice_id ls_pcie_ids[] = { { .compatible = "fsl,ls-pcie" }, + { .compatible = "fsl,ls1028a-pcie", .data = (ulong)&ls1028a_drvdata }, { } }; diff --git a/drivers/qe/Kconfig b/drivers/qe/Kconfig index 553ed5780e..c44a81f69a 100644 --- a/drivers/qe/Kconfig +++ b/drivers/qe/Kconfig @@ -18,6 +18,10 @@ config U_QE help Choose this option to add support for U QUICC Engine. +config SYS_QE_FW_ADDR + hex "QE Firmware Address" + depends on FMAN_ENET || QE || U_QE + default 0x0 choice prompt "QUICC Engine FMan ethernet firmware location" depends on FMAN_ENET || QE diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index 2b473d70f6..3c9a69598a 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -553,6 +553,8 @@ static const struct dm_serial_ops lpuart_serial_ops = { static const struct udevice_id lpuart_serial_ids[] = { { .compatible = "fsl,ls1021a-lpuart", .data = LPUART_FLAG_REGMAP_32BIT_REG | LPUART_FLAG_REGMAP_ENDIAN_BIG }, + { .compatible = "fsl,ls1028a-lpuart", + .data = LPUART_FLAG_REGMAP_32BIT_REG }, { .compatible = "fsl,imx7ulp-lpuart", .data = LPUART_FLAG_REGMAP_32BIT_REG }, { .compatible = "fsl,vf610-lpuart"}, diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index 8fe3508c64..62444e408a 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -586,8 +586,9 @@ static int fsl_dspi_of_to_plat(struct udevice *bus) if (fdtdec_get_bool(blob, node, "big-endian")) plat->flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG; - plat->num_chipselect = - fdtdec_get_int(blob, node, "num-cs", FSL_DSPI_MAX_CHIPSELECT); + plat->num_chipselect = fdtdec_get_int(blob, node, + "spi-num-chipselects", + FSL_DSPI_MAX_CHIPSELECT); addr = dev_read_addr(bus); if (addr == FDT_ADDR_T_NONE) { @@ -654,6 +655,7 @@ static const struct dm_spi_ops fsl_dspi_ops = { static const struct udevice_id fsl_dspi_ids[] = { { .compatible = "fsl,vf610-dspi" }, + { .compatible = "fsl,ls1021a-v1.0-dspi" }, { } }; diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index 43564c9fba..ee0c064f1f 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -29,7 +29,7 @@ enum usb_dr_mode usb_get_dr_mode(ofnode node) dr_mode = ofnode_read_string(node, "dr_mode"); if (!dr_mode) { - pr_err("usb dr_mode not found\n"); + pr_debug("usb dr_mode not found\n"); return USB_DR_MODE_UNKNOWN; } @@ -64,7 +64,7 @@ enum usb_device_speed usb_get_maximum_speed(ofnode node) max_speed = ofnode_read_string(node, "maximum-speed"); if (!max_speed) { - pr_err("usb maximum-speed not found\n"); + pr_debug("usb maximum-speed not found\n"); return USB_SPEED_UNKNOWN; } diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 93707e05fb..62aa65bf0c 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -53,6 +53,16 @@ config USB_DWC3_UNIPHIER Support of USB2/3 functionality in Socionext UniPhier platforms. Say 'Y' here if you have one such device. +config USB_DWC3_LAYERSCAPE + bool "Freescale Layerscape platform support" + depends on DM_USB && USB_DWC3 + depends on !USB_XHCI_FSL + help + Select this for Freescale Layerscape Platforms. + + Host and Peripheral operation modes are supported. OTG is not + supported. + menu "PHY Subsystem" config USB_DWC3_PHY_OMAP diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 6e3e024e97..0dd1ba87cd 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -11,5 +11,6 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_MESON_GXL) += dwc3-meson-gxl.o obj-$(CONFIG_USB_DWC3_GENERIC) += dwc3-generic.o obj-$(CONFIG_USB_DWC3_UNIPHIER) += dwc3-uniphier.o +obj-$(CONFIG_USB_DWC3_LAYERSCAPE) += dwc3-layerscape.o obj-$(CONFIG_USB_DWC3_PHY_OMAP) += ti_usb_phy.o obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG) += samsung_usb_phy.o diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index dfd7cf683f..ce1c0e88c2 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -93,6 +93,27 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) return 0; } +/* + * dwc3_frame_length_adjustment - Adjusts frame length if required + * @dwc3: Pointer to our controller context structure + * @fladj: Value of GFLADJ_30MHZ to adjust frame length + */ +static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) +{ + u32 reg; + + if (dwc->revision < DWC3_REVISION_250A) + return; + + if (fladj == 0) + return; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg &= ~DWC3_GFLADJ_30MHZ_MASK; + reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj; + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); +} + /** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure @@ -441,6 +462,53 @@ static void dwc3_phy_setup(struct dwc3 *dwc) mdelay(100); } +/* set global incr burst type configuration registers */ +static void dwc3_set_incr_burst_type(struct dwc3 *dwc) +{ + struct udevice *dev = dwc->dev; + u32 cfg; + + if (!dwc->incrx_size) + return; + + cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); + + /* Enable Undefined Length INCR Burst and Enable INCRx Burst */ + cfg &= ~DWC3_GSBUSCFG0_INCRBRST_MASK; + if (dwc->incrx_mode) + cfg |= DWC3_GSBUSCFG0_INCRBRSTENA; + switch (dwc->incrx_size) { + case 256: + cfg |= DWC3_GSBUSCFG0_INCR256BRSTENA; + break; + case 128: + cfg |= DWC3_GSBUSCFG0_INCR128BRSTENA; + break; + case 64: + cfg |= DWC3_GSBUSCFG0_INCR64BRSTENA; + break; + case 32: + cfg |= DWC3_GSBUSCFG0_INCR32BRSTENA; + break; + case 16: + cfg |= DWC3_GSBUSCFG0_INCR16BRSTENA; + break; + case 8: + cfg |= DWC3_GSBUSCFG0_INCR8BRSTENA; + break; + case 4: + cfg |= DWC3_GSBUSCFG0_INCR4BRSTENA; + break; + case 1: + break; + default: + dev_err(dev, "Invalid property\n"); + break; + } + + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg); +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -569,6 +637,11 @@ static int dwc3_core_init(struct dwc3 *dwc) if (ret) goto err1; + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dwc, dwc->fladj); + + dwc3_set_incr_burst_type(dwc); + return 0; err1: @@ -892,6 +965,8 @@ void dwc3_of_parse(struct dwc3 *dwc) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u32 val; + int i; /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; @@ -958,6 +1033,26 @@ void dwc3_of_parse(struct dwc3 *dwc) dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); + + dev_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj); + + /* + * Handle property "snps,incr-burst-type-adjustment". + * Get the number of value from this property: + * result <= 0, means this property is not supported. + * result = 1, means INCRx burst mode supported. + * result > 1, means undefined length burst mode supported. + */ + dwc->incrx_mode = INCRX_BURST_MODE; + dwc->incrx_size = 0; + for (i = 0; i < 8; i++) { + if (dev_read_u32_index(dev, "snps,incr-burst-type-adjustment", + i, &val)) + break; + + dwc->incrx_mode = INCRX_UNDEF_LENGTH_BURST_MODE; + dwc->incrx_size = max(dwc->incrx_size, val); + } } int dwc3_init(struct dwc3 *dwc) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 1502cb859a..d7cce3a861 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -115,6 +115,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GHWPARAMS8 0xc600 +#define DWC3_GFLADJ 0xc630 /* Device Registers */ #define DWC3_DCFG 0xc700 @@ -138,6 +139,17 @@ /* Bit fields */ +/* Global SoC Bus Configuration INCRx Register 0 */ +#define DWC3_GSBUSCFG0_INCR256BRSTENA (1 << 7) /* INCR256 burst */ +#define DWC3_GSBUSCFG0_INCR128BRSTENA (1 << 6) /* INCR128 burst */ +#define DWC3_GSBUSCFG0_INCR64BRSTENA (1 << 5) /* INCR64 burst */ +#define DWC3_GSBUSCFG0_INCR32BRSTENA (1 << 4) /* INCR32 burst */ +#define DWC3_GSBUSCFG0_INCR16BRSTENA (1 << 3) /* INCR16 burst */ +#define DWC3_GSBUSCFG0_INCR8BRSTENA (1 << 2) /* INCR8 burst */ +#define DWC3_GSBUSCFG0_INCR4BRSTENA (1 << 1) /* INCR4 burst */ +#define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */ +#define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff + /* Global Configuration Register */ #define DWC3_GCTL_PWRDNSCALE(n) ((n) << 19) #define DWC3_GCTL_U2RSTECN (1 << 16) @@ -233,6 +245,10 @@ /* Global HWPARAMS6 Register */ #define DWC3_GHWPARAMS6_EN_FPGA (1 << 7) +/* Global Frame Length Adjustment Register */ +#define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) +#define DWC3_GFLADJ_30MHZ_MASK 0x3f + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) @@ -812,6 +828,9 @@ struct dwc3 { u8 test_mode_nr; u8 lpm_nyet_threshold; u8 hird_threshold; + u32 fladj; + u8 incrx_mode; + u32 incrx_size; unsigned delayed_status:1; unsigned ep0_bounced:1; @@ -849,6 +868,9 @@ struct dwc3 { struct list_head list; }; +#define INCRX_BURST_MODE 0 +#define INCRX_UNDEF_LENGTH_BURST_MODE 1 + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/dwc3-layerscape.c b/drivers/usb/dwc3/dwc3-layerscape.c new file mode 100644 index 0000000000..79cf71f7a8 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-layerscape.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Layerscape DWC3 Glue layer + * + * Copyright (C) 2021 Michael Walle <michael@walle.cc> + * + * Based on dwc3-generic.c. + */ + +#include <common.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dwc3-uboot.h> +#include <linux/usb/gadget.h> +#include <usb.h> +#include "core.h" +#include "gadget.h" +#include <usb/xhci.h> + +struct dwc3_layerscape_plat { + fdt_addr_t base; + u32 maximum_speed; + enum usb_dr_mode dr_mode; +}; + +struct dwc3_layerscape_priv { + void *base; + struct dwc3 dwc3; + struct phy_bulk phys; +}; + +struct dwc3_layerscape_host_priv { + struct xhci_ctrl xhci_ctrl; + struct dwc3_layerscape_priv gen_priv; +}; + +static int dwc3_layerscape_probe(struct udevice *dev, + struct dwc3_layerscape_priv *priv) +{ + int rc; + struct dwc3_layerscape_plat *plat = dev_get_plat(dev); + struct dwc3 *dwc3 = &priv->dwc3; + + dwc3->dev = dev; + dwc3->maximum_speed = plat->maximum_speed; + dwc3->dr_mode = plat->dr_mode; + if (CONFIG_IS_ENABLED(OF_CONTROL)) + dwc3_of_parse(dwc3); + + rc = dwc3_setup_phy(dev, &priv->phys); + if (rc && rc != -ENOTSUPP) + return rc; + + priv->base = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE); + dwc3->regs = priv->base + DWC3_GLOBALS_REGS_START; + + rc = dwc3_init(dwc3); + if (rc) { + unmap_physmem(priv->base, MAP_NOCACHE); + return rc; + } + + return 0; +} + +static int dwc3_layerscape_remove(struct udevice *dev, + struct dwc3_layerscape_priv *priv) +{ + struct dwc3 *dwc3 = &priv->dwc3; + + dwc3_remove(dwc3); + dwc3_shutdown_phy(dev, &priv->phys); + unmap_physmem(dwc3->regs, MAP_NOCACHE); + + return 0; +} + +static int dwc3_layerscape_of_to_plat(struct udevice *dev) +{ + struct dwc3_layerscape_plat *plat = dev_get_plat(dev); + ofnode node = dev_ofnode(dev); + + plat->base = dev_read_addr(dev); + + plat->maximum_speed = usb_get_maximum_speed(node); + if (plat->maximum_speed == USB_SPEED_UNKNOWN) { + dev_dbg(dev, "No USB maximum speed specified. Using super speed\n"); + plat->maximum_speed = USB_SPEED_SUPER; + } + + plat->dr_mode = usb_get_dr_mode(node); + if (plat->dr_mode == USB_DR_MODE_UNKNOWN) { + dev_err(dev, "Invalid usb mode setup\n"); + return -ENODEV; + } + + return 0; +} + +#if CONFIG_IS_ENABLED(DM_USB_GADGET) +int dm_usb_gadget_handle_interrupts(struct udevice *dev) +{ + struct dwc3_layerscape_priv *priv = dev_get_priv(dev); + + dwc3_gadget_uboot_handle_interrupt(&priv->dwc3); + + return 0; +} + +static int dwc3_layerscape_peripheral_probe(struct udevice *dev) +{ + struct dwc3_layerscape_priv *priv = dev_get_priv(dev); + + return dwc3_layerscape_probe(dev, priv); +} + +static int dwc3_layerscape_peripheral_remove(struct udevice *dev) +{ + struct dwc3_layerscape_priv *priv = dev_get_priv(dev); + + return dwc3_layerscape_remove(dev, priv); +} + +U_BOOT_DRIVER(dwc3_layerscape_peripheral) = { + .name = "dwc3-layerscape-peripheral", + .id = UCLASS_USB_GADGET_GENERIC, + .of_to_plat = dwc3_layerscape_of_to_plat, + .probe = dwc3_layerscape_peripheral_probe, + .remove = dwc3_layerscape_peripheral_remove, + .priv_auto = sizeof(struct dwc3_layerscape_priv), + .plat_auto = sizeof(struct dwc3_layerscape_plat), +}; +#endif + +#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || \ + !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST) +static int dwc3_layerscape_host_probe(struct udevice *dev) +{ + struct xhci_hcor *hcor; + struct xhci_hccr *hccr; + struct dwc3_layerscape_host_priv *priv = dev_get_priv(dev); + int rc; + + rc = dwc3_layerscape_probe(dev, &priv->gen_priv); + if (rc) + return rc; + + hccr = priv->gen_priv.base; + hcor = priv->gen_priv.base + HC_LENGTH(xhci_readl(&hccr->cr_capbase)); + + return xhci_register(dev, hccr, hcor); +} + +static int dwc3_layerscape_host_remove(struct udevice *dev) +{ + struct dwc3_layerscape_host_priv *priv = dev_get_priv(dev); + int rc; + + rc = xhci_deregister(dev); + if (rc) + return rc; + + return dwc3_layerscape_remove(dev, &priv->gen_priv); +} + +U_BOOT_DRIVER(dwc3_layerscape_host) = { + .name = "dwc3-layerscape-host", + .id = UCLASS_USB, + .of_to_plat = dwc3_layerscape_of_to_plat, + .probe = dwc3_layerscape_host_probe, + .remove = dwc3_layerscape_host_remove, + .priv_auto = sizeof(struct dwc3_layerscape_host_priv), + .plat_auto = sizeof(struct dwc3_layerscape_plat), + .ops = &xhci_usb_ops, + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif + +static int dwc3_layerscape_bind(struct udevice *dev) +{ + ofnode node = dev_ofnode(dev); + const char *name = ofnode_get_name(node); + enum usb_dr_mode dr_mode; + char *driver; + + dr_mode = usb_get_dr_mode(node); + + switch (dr_mode) { +#if CONFIG_IS_ENABLED(DM_USB_GADGET) + case USB_DR_MODE_PERIPHERAL: + dev_dbg(dev, "Using peripheral mode\n"); + driver = "dwc3-layerscape-peripheral"; + break; +#endif +#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD) + case USB_DR_MODE_HOST: + dev_dbg(dev, "Using host mode\n"); + driver = "dwc3-layerscape-host"; + break; +#endif + default: + dev_dbg(dev, "Unsupported dr_mode\n"); + return -ENODEV; + }; + + return device_bind_driver_to_node(dev, driver, name, node, NULL); +} + +static const struct udevice_id dwc3_layerscape_ids[] = { + { .compatible = "fsl,layerscape-dwc3" }, + { .compatible = "fsl,ls1028a-dwc3" }, + { } +}; + +U_BOOT_DRIVER(dwc3_layerscape_wrapper) = { + .name = "dwc3-layerscape-wrapper", + .id = UCLASS_NOP, + .of_match = dwc3_layerscape_ids, + .bind = dwc3_layerscape_bind, +}; diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c index f062f12ade..80871908dc 100644 --- a/drivers/usb/host/xhci-fsl.c +++ b/drivers/usb/host/xhci-fsl.c @@ -159,6 +159,7 @@ static int xhci_fsl_remove(struct udevice *dev) static const struct udevice_id xhci_usb_ids[] = { { .compatible = "fsl,layerscape-dwc3", }, + { .compatible = "fsl,ls1028a-dwc3", }, { } }; diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index bec8827ceb..0d6fb12065 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -134,7 +134,7 @@ static const struct wdt_ops sp805_wdt_ops = { }; static const struct udevice_id sp805_wdt_ids[] = { - { .compatible = "arm,sp805-wdt" }, + { .compatible = "arm,sp805" }, {} }; |