diff options
author | Tom Rini <trini@konsulko.com> | 2023-09-21 10:51:58 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-09-21 10:51:58 -0400 |
commit | 5d2fae79c7d60eaf7f50322e4ec125d2f58544e9 (patch) | |
tree | e1afcf0f540ca40908a835cca26e2d61fc098304 /drivers | |
parent | bcfde74974e2c399e414e8c55665bfed2612da5d (diff) | |
parent | a3ade3dae4d93f9b5282ddb4885d69161729ec6d (diff) |
Merge tag 'xilinx-for-v2024.01-rc1-v2' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next
Xilinx changes for v2024.01-rc1
clk:
- Dont return error when assigned-clocks is empty or missing
dm:
- Support reading a single indexed u64 value
- Add support for reading bootscript address/flash address from DT
cmd:
- Fix flash_is_unlocked API
fpga:
- Define fpga_load() for debug build
global:
- U-Boot project name cleanup (next2)
net:
- zynq_gem: Use generic_phy_valid() helper
- axienet: Convert to ofnode functions
- gmii2rgmii: Read bridge address from DT
pytest:
- skip tpm2_startup when env__tpm_device_test_skip=True
spi-nor:
- Add mx25u25635f support
- zynqmp_qspi: Tune cache behavior
trace:
- Fix flyrecord alignment issue
xilinx:
- Move scriptaddr to DT as bootscr-address
- Pick script_offset_f/script_size_f from DT as bootscr-flash-offset/size
- Do not generate distro boot variables if disabled
versal:
- Extend memory ranges to cover HBM
- Enable TPM, sha1sum and KASLRSEED
- Fix distroboot prioritization in connection to available devices
- Clean mini targets bootcommand
- Fix clock driver
versal-net:
- Enable TPM, sha1sum and KASLRSEED
- Fix distroboot prioritization in connection to available devices
zynqmp;
- Allow AES to run from SPL
- Enable CMD_KASLRSEED
- Add proper dependencies for USB and remove ZYNQMP_USB
- Fix user si570 default frequency for zcu* boards
- Cover SOM rev2 revision
- Various DT changes
- Add firmware and pinctrl support for tristate configuration
(high impedance/output enable)
- Add output-enable pins to SOMs
- Fix distroboot prioritization in connection to available devices
- Read bootscript address/flash address from DT
- Fix pcap_prog address
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/clk-uclass.c | 8 | ||||
-rw-r--r-- | drivers/clk/clk_versal.c | 98 | ||||
-rw-r--r-- | drivers/core/of_access.c | 16 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 89 | ||||
-rw-r--r-- | drivers/firmware/firmware-zynqmp.c | 13 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-ids.c | 1 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 5 | ||||
-rw-r--r-- | drivers/net/xilinx_axi_emac.c | 50 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-zynqmp.c | 15 | ||||
-rw-r--r-- | drivers/spi/zynqmp_gqspi.c | 4 |
10 files changed, 233 insertions, 66 deletions
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index dc3e9d6a26..f186fcbcdb 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -329,7 +329,13 @@ static int clk_set_default_rates(struct udevice *dev, dev_dbg(dev, "could not get assigned clock %d (err = %d)\n", index, ret); - continue; + /* Skip if it is empty */ + if (ret == -ENOENT) { + ret = 0; + continue; + } + + return ret; } /* This is clk provider device trying to program itself diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index b3b3333123..2e004beca2 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -68,6 +68,13 @@ #define CLOCK_NODE_TYPE_DIV 4 #define CLOCK_NODE_TYPE_GATE 6 +#define PM_CLK_REF_CLK (0x830c06aU) +#define PM_CLK_PL_ALT_REF_CLK (0x830c06bU) +#define PM_CLK_MUXED_IRO (0x830c06cU) +#define PM_CLK_EMIO (0x830c071U) + +#define TOPOLOGY_TYPE_FIXEDFACTOR 0x3 + enum clk_type { CLK_TYPE_OUTPUT, CLK_TYPE_EXTERNAL, @@ -365,48 +372,37 @@ static u32 versal_clock_set_div(u32 clk_id, u32 div) return div; } -static u64 versal_clock_ref(u32 clk_id) +static u64 versal_clock_get_ref_rate(u32 clk_id) { - u32 ret_payload[PAYLOAD_ARG_CNT]; - int ref; - - xilinx_pm_request(PM_CLOCK_GETPARENT, clk_id, 0, 0, 0, ret_payload); - ref = ret_payload[0]; - if (!(ref & 1)) + if (clk_id == PM_CLK_REF_CLK || clk_id == PM_CLK_MUXED_IRO || clk_id == PM_CLK_EMIO) return ref_clk; - if (ref & 2) + else if (clk_id == PM_CLK_PL_ALT_REF_CLK) return pl_alt_ref_clk; - return 0; + else + return 0; } -static u64 versal_clock_get_pll_rate(u32 clk_id) +static int versal_clock_get_fixed_factor_rate(u32 clock_id, u32 parent_id) { + struct versal_pm_query_data qdata = {0}; u32 ret_payload[PAYLOAD_ARG_CNT]; - u32 fbdiv; - u32 res; - u32 frac; - u64 freq; - u32 parent_rate, parent_id; - u32 id = clk_id & 0xFFF; + u32 mult, div; + u32 parent_rate; + int ret; - xilinx_pm_request(PM_CLOCK_GETSTATE, clk_id, 0, 0, 0, ret_payload); - res = ret_payload[1]; - if (!res) { - printf("0%x PLL not enabled\n", clk_id); - return 0; - } + qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS; + qdata.arg1 = clock_id; - parent_id = clock[clock[id].parent[0].id].clk_id; - parent_rate = versal_clock_ref(parent_id); + ret = versal_pm_query(qdata, ret_payload); + if (ret) + return ret; - xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, ret_payload); - fbdiv = ret_payload[1]; - xilinx_pm_request(PM_CLOCK_PLL_GETPARAM, clk_id, 2, 0, 0, ret_payload); - frac = ret_payload[1]; + mult = ret_payload[1]; + div = ret_payload[2]; - freq = (fbdiv * parent_rate) >> (1 << frac); + parent_rate = versal_clock_get_ref_rate(parent_id); + return parent_rate * mult / div; - return freq; } static u32 versal_clock_mux(u32 clk_id) @@ -437,6 +433,37 @@ static u32 versal_clock_get_parentid(u32 clk_id) return clock[clock[id].parent[parent_id].id].clk_id; } +static u64 versal_clock_get_pll_rate(u32 clk_id) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + u32 fbdiv; + u32 res; + u32 frac; + u64 freq; + u32 parent_rate, parent_id, parent_ref_clk_id; + u32 id = clk_id & 0xFFF; + + xilinx_pm_request(PM_CLOCK_GETSTATE, clk_id, 0, 0, 0, ret_payload); + res = ret_payload[1]; + if (!res) { + printf("0%x PLL not enabled\n", clk_id); + return 0; + } + + parent_id = clock[clock[id].parent[0].id].clk_id; + parent_ref_clk_id = versal_clock_get_parentid(parent_id); + parent_rate = versal_clock_get_ref_rate(parent_ref_clk_id); + + xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, ret_payload); + fbdiv = ret_payload[1]; + xilinx_pm_request(PM_CLOCK_PLL_GETPARAM, clk_id, 2, 0, 0, ret_payload); + frac = ret_payload[1]; + + freq = (fbdiv * parent_rate) >> (1 << frac); + + return freq; +} + static u32 versal_clock_gate(u32 clk_id) { u32 id = clk_id & 0xFFF; @@ -479,14 +506,19 @@ static u64 versal_clock_calc(u32 clk_id) u32 parent_id; u64 clk_rate; u32 div; + struct clock_topology topology; if (versal_clock_pll(clk_id, &clk_rate)) return clk_rate; parent_id = versal_clock_get_parentid(clk_id); if (((parent_id >> NODE_SUBCLASS_SHIFT) & - NODE_CLASS_MASK) == NODE_SUBCLASS_CLOCK_REF) - return versal_clock_ref(clk_id); + NODE_CLASS_MASK) == NODE_SUBCLASS_CLOCK_REF) { + topology = clock[clk_id & 0x3FF].node[0]; + if (topology.type == TOPOLOGY_TYPE_FIXEDFACTOR) + return versal_clock_get_fixed_factor_rate(clk_id, parent_id); + return versal_clock_get_ref_rate(parent_id); + } if (!parent_id) return 0; @@ -505,7 +537,7 @@ static int versal_clock_get_rate(u32 clk_id, u64 *clk_rate) { if (((clk_id >> NODE_SUBCLASS_SHIFT) & NODE_CLASS_MASK) == NODE_SUBCLASS_CLOCK_REF) - *clk_rate = versal_clock_ref(clk_id); + *clk_rate = versal_clock_get_ref_rate(clk_id); if (versal_clock_pll(clk_id, clk_rate)) return 0; diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 57f10445b1..1bb4d8eab7 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -570,26 +570,34 @@ int of_read_u32_index(const struct device_node *np, const char *propname, return 0; } -int of_read_u64(const struct device_node *np, const char *propname, u64 *outp) +int of_read_u64_index(const struct device_node *np, const char *propname, + int index, u64 *outp) { const __be64 *val; debug("%s: %s: ", __func__, propname); if (!np) return -EINVAL; - val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + + val = of_find_property_value_of_size(np, propname, + sizeof(*outp) * (index + 1)); if (IS_ERR(val)) { debug("(not found)\n"); return PTR_ERR(val); } - *outp = be64_to_cpup(val); + *outp = be64_to_cpup(val + index); debug("%#llx (%lld)\n", (unsigned long long)*outp, - (unsigned long long)*outp); + (unsigned long long)*outp); return 0; } +int of_read_u64(const struct device_node *np, const char *propname, u64 *outp) +{ + return of_read_u64_index(np, propname, 0, outp); +} + int of_property_match_string(const struct device_node *np, const char *propname, const char *string) { diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index a4dc9bde08..ff0a5b5164 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -344,6 +344,36 @@ int ofnode_read_u32_index(ofnode node, const char *propname, int index, return 0; } +int ofnode_read_u64_index(ofnode node, const char *propname, int index, + u64 *outp) +{ + const fdt64_t *cell; + int len; + + assert(ofnode_valid(node)); + + if (ofnode_is_np(node)) + return of_read_u64_index(ofnode_to_np(node), propname, index, + outp); + + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); + if (!cell) { + debug("(not found)\n"); + return -EINVAL; + } + + if (len < (sizeof(u64) * (index + 1))) { + debug("(not large enough)\n"); + return -EOVERFLOW; + } + + *outp = fdt64_to_cpu(cell[index]); + debug("%#llx (%lld)\n", *outp, *outp); + + return 0; +} + u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index, u32 def) { @@ -1563,6 +1593,65 @@ const char *ofnode_conf_read_str(const char *prop_name) return ofnode_read_string(node, prop_name); } +int ofnode_read_bootscript_address(u64 *bootscr_address, u64 *bootscr_offset) +{ + int ret; + ofnode uboot; + + *bootscr_address = 0; + *bootscr_offset = 0; + + uboot = ofnode_path("/options/u-boot"); + if (!ofnode_valid(uboot)) { + debug("%s: Missing /u-boot node\n", __func__); + return -EINVAL; + } + + ret = ofnode_read_u64(uboot, "bootscr-address", bootscr_address); + if (ret) { + ret = ofnode_read_u64(uboot, "bootscr-ram-offset", + bootscr_offset); + if (ret) + return -EINVAL; + } + + return 0; +} + +int ofnode_read_bootscript_flash(u64 *bootscr_flash_offset, + u64 *bootscr_flash_size) +{ + int ret; + ofnode uboot; + + *bootscr_flash_offset = 0; + *bootscr_flash_size = 0; + + uboot = ofnode_path("/options/u-boot"); + if (!ofnode_valid(uboot)) { + debug("%s: Missing /u-boot node\n", __func__); + return -EINVAL; + } + + ret = ofnode_read_u64(uboot, "bootscr-flash-offset", + bootscr_flash_offset); + if (ret) + return -EINVAL; + + ret = ofnode_read_u64(uboot, "bootscr-flash-size", + bootscr_flash_size); + if (ret) + return -EINVAL; + + if (!bootscr_flash_size) { + debug("bootscr-flash-size is zero. Ignoring properties!\n"); + *bootscr_flash_offset = 0; + return -EINVAL; + } + + return 0; +} + ofnode ofnode_get_phy_node(ofnode node) { /* DT node properties that reference a PHY node */ diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index ab4c4f1a69..43fb7fa778 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -195,6 +195,19 @@ int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value) return ret; } +int zynqmp_pm_feature(const u32 api_id) +{ + int ret; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + /* Check feature check API version */ + ret = xilinx_pm_request(PM_FEATURE_CHECK, api_id, 0, 0, 0, + ret_payload); + + /* Return feature check version */ + return ret_payload[1] & FIRMWARE_VERSION_MASK; +} + int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id) { int ret; diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 4587215984..b03dd1cd08 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -249,6 +249,7 @@ const struct flash_info spi_nor_ids[] = { { INFO("mx25u6435f", 0xc22537, 0, 64 * 1024, 128, SECT_4K) }, { INFO("mx25l12805d", 0xc22018, 0, 64 * 1024, 256, SECT_4K) }, { INFO("mx25u12835f", 0xc22538, 0, 64 * 1024, 256, SECT_4K) }, + { INFO("mx25u25635f", 0xc22539, 0, 64 * 1024, 512, SECT_4K) }, { INFO("mx25u51245g", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { INFO("mx25l12855e", 0xc22618, 0, 64 * 1024, 256, 0) }, diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index d50fd505e5..63b3e46f10 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -807,7 +807,10 @@ static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus, ofnode_for_each_subnode(node, dev_ofnode(dev)) { node = ofnode_by_compatible(node, "xlnx,gmii-to-rgmii-1.0"); if (ofnode_valid(node)) { - phydev = phy_device_create(bus, 0, + int gmiirgmii_phyaddr; + + gmiirgmii_phyaddr = ofnode_read_u32_default(node, "reg", 0); + phydev = phy_device_create(bus, gmiirgmii_phyaddr, PHY_GMII2RGMII_ID, false); if (phydev) phydev->node = node; diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 39cb3cc260..54f2232768 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -112,7 +112,7 @@ struct axidma_plat { int pcsaddr; int phyaddr; u8 eth_hasnobuf; - int phy_of_handle; + ofnode phynode; enum emac_variant mactype; }; @@ -127,7 +127,7 @@ struct axidma_priv { struct phy_device *phydev; struct mii_dev *bus; u8 eth_hasnobuf; - int phy_of_handle; + ofnode phynode; enum emac_variant mactype; }; @@ -335,8 +335,8 @@ static int axiemac_phy_init(struct udevice *dev) phydev->supported &= supported; phydev->advertising = phydev->supported; priv->phydev = phydev; - if (priv->phy_of_handle) - priv->phydev->node = offset_to_ofnode(priv->phy_of_handle); + if (ofnode_valid(priv->phynode)) + priv->phydev->node = priv->phynode; phy_config(phydev); return 0; @@ -839,7 +839,7 @@ static int axi_emac_probe(struct udevice *dev) priv->eth_hasnobuf = plat->eth_hasnobuf; priv->pcsaddr = plat->pcsaddr; priv->phyaddr = plat->phyaddr; - priv->phy_of_handle = plat->phy_of_handle; + priv->phynode = plat->phynode; priv->interface = pdata->phy_interface; if (IS_ENABLED(CONFIG_DM_ETH_PHY)) @@ -894,20 +894,21 @@ static int axi_emac_of_to_plat(struct udevice *dev) { struct axidma_plat *plat = dev_get_plat(dev); struct eth_pdata *pdata = &plat->eth_pdata; - int node = dev_of_offset(dev); - int offset = 0; + struct ofnode_phandle_args pcs_node, axistream_node; + ofnode phynode; + int ret; pdata->iobase = dev_read_addr(dev); plat->mactype = dev_get_driver_data(dev); - offset = fdtdec_lookup_phandle(gd->fdt_blob, node, - "axistream-connected"); - if (offset <= 0) { + ret = dev_read_phandle_with_args(dev, "axistream-connected", NULL, 0, 0, + &axistream_node); + if (ret) { printf("%s: axistream is not found\n", __func__); return -EINVAL; } - plat->dmatx = (struct axidma_reg *)fdtdec_get_addr_size_auto_parent - (gd->fdt_blob, 0, offset, "reg", 0, NULL, false); + + plat->dmatx = (struct axidma_reg *)ofnode_get_addr(axistream_node.node); if (!plat->dmatx) { printf("%s: axi_dma register space not found\n", __func__); return -EINVAL; @@ -918,30 +919,27 @@ static int axi_emac_of_to_plat(struct udevice *dev) /* PHYAD 0 always redirects to the PCS/PMA PHY */ plat->pcsaddr = 0; - offset = fdtdec_lookup_phandle(gd->fdt_blob, node, - "phy-handle"); - if (offset > 0) { + phynode = dev_get_phy_node(dev); + if (ofnode_valid(phynode)) { if (!(IS_ENABLED(CONFIG_DM_ETH_PHY))) - plat->phyaddr = fdtdec_get_int(gd->fdt_blob, - offset, - "reg", -1); - plat->phy_of_handle = offset; + plat->phyaddr = ofnode_read_u32_default(phynode, + "reg", -1); + plat->phynode = phynode; } pdata->phy_interface = dev_read_phy_mode(dev); if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) return -EINVAL; - plat->eth_hasnobuf = fdtdec_get_bool(gd->fdt_blob, node, - "xlnx,eth-hasnobuf"); + plat->eth_hasnobuf = dev_read_bool(dev, "xlnx,eth-hasnobuf"); if (pdata->phy_interface == PHY_INTERFACE_MODE_SGMII || pdata->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { - offset = fdtdec_lookup_phandle(gd->fdt_blob, node, - "pcs-handle"); - if (offset > 0) { - plat->pcsaddr = fdtdec_get_int(gd->fdt_blob, - offset, "reg", -1); + ret = dev_read_phandle_with_args(dev, "pcs-handle", NULL, 0, 0, + &pcs_node); + if (!ret) { + plat->pcsaddr = ofnode_read_u32_default(pcs_node.node, + "reg", -1); } } } diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c index 02626a7561..517035961d 100644 --- a/drivers/pinctrl/pinctrl-zynqmp.c +++ b/drivers/pinctrl/pinctrl-zynqmp.c @@ -158,6 +158,12 @@ static int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, u32 valu { int ret; + if (param == PM_PINCTRL_CONFIG_TRI_STATE) { + ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET); + if (ret < PM_PINCTRL_PARAM_SET_VERSION) + return -EOPNOTSUPP; + } + /* Request the pin first */ ret = xilinx_pm_request(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL); if (ret) { @@ -467,6 +473,10 @@ static int zynqmp_pinconf_set(struct udevice *dev, unsigned int pin, pin); break; case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + param = PM_PINCTRL_CONFIG_TRI_STATE; + arg = PM_PINCTRL_TRI_STATE_ENABLE; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; case PIN_CONFIG_LOW_POWER_MODE: /* * This cases are mentioned in dts but configurable @@ -475,6 +485,11 @@ static int zynqmp_pinconf_set(struct udevice *dev, unsigned int pin, */ ret = 0; break; + case PIN_CONFIG_OUTPUT_ENABLE: + param = PM_PINCTRL_CONFIG_TRI_STATE; + arg = PM_PINCTRL_TRI_STATE_DISABLE; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; default: dev_warn(dev, "unsupported configuration parameter '%u'\n", param); diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index c4aee279aa..ec59ef5804 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -690,7 +690,7 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); addr = (unsigned long)buf; size = roundup(priv->len, GQSPI_DMA_ALIGN); - flush_dcache_range(addr, addr + size); + invalidate_dcache_range(addr, addr + size); while (priv->len) { zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); @@ -707,6 +707,8 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, return -ETIMEDOUT; } + invalidate_dcache_range(addr, addr + size); + writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr); debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", |