Xilinx changes for v2020.10-rc3

- Fix fdtfile variable setup
- Fix bootm_*/fdt_high/initrd_high variables handling
- Fix Kconfig dependencies for Xilinx drivers
- Fix booting u-boot from lowest memory
- Fix firmware payload argument count for Versal
- Fix dfu configurations
- Fix mio_bank property handling
- Fix and align code around ID detection
- Start to use ENV_VARS_UBOOT_RUNTIME_CONFIG
- Simplify logic around reading MAC from eeprom
- Decrease malloc length for zynqmp mini qspi
- Enable preboot for ZynqMP and Versal

i2c:
- Fix i2c eeprom partitions handling

mmc:
- Fix logic around HS mode enabling and use proper functions
This commit is contained in:
Tom Rini
2020-08-20 14:46:43 -04:00
57 changed files with 458 additions and 242 deletions

View File

@@ -68,23 +68,6 @@
#define CLOCK_NODE_TYPE_DIV 4
#define CLOCK_NODE_TYPE_GATE 6
enum pm_query_id {
PM_QID_INVALID,
PM_QID_CLOCK_GET_NAME,
PM_QID_CLOCK_GET_TOPOLOGY,
PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
PM_QID_CLOCK_GET_PARENTS,
PM_QID_CLOCK_GET_ATTRIBUTES,
PM_QID_PINCTRL_GET_NUM_PINS,
PM_QID_PINCTRL_GET_NUM_FUNCTIONS,
PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
PM_QID_PINCTRL_GET_FUNCTION_NAME,
PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
PM_QID_PINCTRL_GET_PIN_GROUPS,
PM_QID_CLOCK_GET_NUM_CLOCKS,
PM_QID_CLOCK_GET_MAX_DIVISOR,
};
enum clk_type {
CLK_TYPE_OUTPUT,
CLK_TYPE_EXTERNAL,

View File

@@ -37,6 +37,7 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
if (!(zynqmp_power.tx_chan.dev) || !(&zynqmp_power.rx_chan.dev))
return -EINVAL;
debug("%s, Sending IPI message with ID: 0x%0x\n", __func__, req[0]);
msg.buf = (u32 *)req;
msg.len = req_len;
ret = mbox_send(&zynqmp_power.tx_chan, &msg);
@@ -54,14 +55,6 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
return ret;
}
static int send_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
{
if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
return ipi_req(req, req_len, res, res_maxlen);
return xilinx_pm_request(req[0], 0, 0, 0, 0, res);
}
unsigned int zynqmp_firmware_version(void)
{
int ret;
@@ -74,9 +67,9 @@ unsigned int zynqmp_firmware_version(void)
* asking PMUFW again.
**/
if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) {
const u32 request[] = { PM_GET_API_VERSION };
ret = send_req(request, ARRAY_SIZE(request), ret_payload, 2);
ret = xilinx_pm_request(PM_GET_API_VERSION, 0, 0, 0, 0,
ret_payload);
if (ret)
panic("PMUFW is not found - Please load it!\n");
@@ -97,16 +90,13 @@ unsigned int zynqmp_firmware_version(void)
*/
void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
{
const u32 request[] = {
PM_SET_CONFIGURATION,
(u32)((u64)cfg_obj)
};
u32 response = 0;
int err;
u32 ret_payload[PAYLOAD_ARG_CNT];
printf("Loading new PMUFW cfg obj (%ld bytes)\n", size);
err = send_req(request, ARRAY_SIZE(request), &response, 1);
err = xilinx_pm_request(PM_SET_CONFIGURATION, (u32)(u64)cfg_obj, 0, 0,
0, ret_payload);
if (err == XST_PM_NO_ACCESS) {
printf("PMUFW no permission to change config object\n");
return;
@@ -115,10 +105,10 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
if (err)
printf("Cannot load PMUFW configuration object (%d)\n", err);
if (response)
printf("PMUFW returned 0x%08x status!\n", response);
if (ret_payload[0])
printf("PMUFW returned 0x%08x status!\n", ret_payload[0]);
if ((err || response) && IS_ENABLED(CONFIG_SPL_BUILD))
if ((err || ret_payload[0]) && IS_ENABLED(CONFIG_SPL_BUILD))
panic("PMUFW config object loading failed in EL3\n");
}
@@ -164,32 +154,44 @@ U_BOOT_DRIVER(zynqmp_power) = {
int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
u32 arg3, u32 *ret_payload)
{
/*
* Added SIP service call Function Identifier
* Make sure to stay in x0 register
*/
struct pt_regs regs;
debug("%s at EL%d, API ID: 0x%0x\n", __func__, current_el(), api_id);
if (current_el() == 3) {
printf("%s: Can't call SMC from EL3 context\n", __func__);
if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
#if defined(CONFIG_ZYNQMP_IPI)
/*
* Use fixed payload and arg size as the EL2 call. The firmware
* is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
* firmware API is limited by the SMC call size
*/
u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
#else
return -EPERM;
#endif
} else {
/*
* Added SIP service call Function Identifier
* Make sure to stay in x0 register
*/
struct pt_regs regs;
regs.regs[0] = PM_SIP_SVC | api_id;
regs.regs[1] = ((u64)arg1 << 32) | arg0;
regs.regs[2] = ((u64)arg3 << 32) | arg2;
smc_call(&regs);
if (ret_payload) {
ret_payload[0] = (u32)regs.regs[0];
ret_payload[1] = upper_32_bits(regs.regs[0]);
ret_payload[2] = (u32)regs.regs[1];
ret_payload[3] = upper_32_bits(regs.regs[1]);
ret_payload[4] = (u32)regs.regs[2];
}
}
regs.regs[0] = PM_SIP_SVC | api_id;
regs.regs[1] = ((u64)arg1 << 32) | arg0;
regs.regs[2] = ((u64)arg3 << 32) | arg2;
smc_call(&regs);
if (ret_payload) {
ret_payload[0] = (u32)regs.regs[0];
ret_payload[1] = upper_32_bits(regs.regs[0]);
ret_payload[2] = (u32)regs.regs[1];
ret_payload[3] = upper_32_bits(regs.regs[1]);
ret_payload[4] = (u32)regs.regs[2];
}
return regs.regs[0];
return (ret_payload) ? ret_payload[0] : 0;
}
static const struct udevice_id zynqmp_firmware_ids[] = {

View File

@@ -32,7 +32,7 @@ static int versal_load(xilinx_desc *desc, const void *buf, size_t bsize,
ulong bin_buf;
int ret;
u32 buf_lo, buf_hi;
u32 ret_payload[5];
u32 ret_payload[PAYLOAD_ARG_CNT];
bin_buf = versal_align_dma_buffer((ulong *)buf, bsize);

View File

@@ -381,8 +381,8 @@ config MVEBU_GPIO
config ZYNQ_GPIO
bool "Zynq GPIO driver"
depends on DM_GPIO && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL)
default y
depends on DM_GPIO
default y if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
help
Supports GPIO access on Zynq SoC.

View File

@@ -88,7 +88,7 @@ config SYS_I2C_FSL
config SYS_I2C_CADENCE
tristate "Cadence I2C Controller"
depends on DM_I2C && (ARCH_ZYNQ || ARM64)
depends on DM_I2C
help
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.

View File

@@ -24,10 +24,12 @@
struct ipi_int_regs {
u32 trig; /* 0x0 */
u32 obs; /* 0x4 */
u32 ist; /* 0x8 */
u32 imr; /* 0xC */
u32 ier; /* 0x10 */
u32 idr; /* 0x14 */
u32 dummy0;
u32 dummy1;
u32 isr; /* 0x10 */
u32 imr; /* 0x14 */
u32 ier; /* 0x18 */
u32 idr; /* 0x1C */
};
#define ipi_int_apu ((struct ipi_int_regs *)IPI_INT_REG_BASE_APU)
@@ -66,6 +68,10 @@ static int zynqmp_ipi_recv(struct mbox_chan *chan, void *data)
struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev);
u32 *mbx = (u32 *)zynqmp->local_res_regs;
/*
* PMU Firmware does not trigger IPI interrupt for API call responses so
* there is no need to check ISR flags
*/
for (size_t i = 0; i < msg->len; i++)
msg->buf[i] = readl(&mbx[i]);

View File

@@ -301,19 +301,20 @@ static int i2c_eeprom_partition_probe(struct udevice *dev)
static int i2c_eeprom_partition_ofdata_to_platdata(struct udevice *dev)
{
struct i2c_eeprom_partition *priv = dev_get_priv(dev);
u32 offset, size;
u32 reg[2];
int ret;
ret = dev_read_u32(dev, "offset", &offset);
ret = dev_read_u32_array(dev, "reg", reg, 2);
if (ret)
return ret;
ret = dev_read_u32(dev, "size", &size);
if (ret)
return ret;
if (!reg[1])
return -EINVAL;
priv->offset = offset;
priv->size = size;
priv->offset = reg[0];
priv->size = reg[1];
debug("%s: base %x, size %x\n", __func__, priv->offset, priv->size);
return 0;
}

View File

@@ -653,7 +653,6 @@ config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
config MMC_SDHCI_ZYNQ
bool "Arasan SDHCI controller support"
depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
depends on DM_MMC && OF_CONTROL && BLK
depends on MMC_SDHCI
help

View File

@@ -748,9 +748,9 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
"sdhci-caps-mask", 0);
dt_caps = dev_read_u64_default(host->mmc->dev,
"sdhci-caps", 0);
caps = ~(u32)dt_caps_mask &
caps = ~lower_32_bits(dt_caps_mask) &
sdhci_readl(host, SDHCI_CAPABILITIES);
caps |= (u32)dt_caps;
caps |= lower_32_bits(dt_caps);
#else
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
#endif
@@ -793,9 +793,9 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
/* Check whether the clock multiplier is supported or not */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
#if CONFIG_IS_ENABLED(DM_MMC)
caps_1 = ~(u32)(dt_caps_mask >> 32) &
caps_1 = ~upper_32_bits(dt_caps_mask) &
sdhci_readl(host, SDHCI_CAPABILITIES_1);
caps_1 |= (u32)(dt_caps >> 32);
caps_1 |= upper_32_bits(dt_caps);
#else
caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
#endif
@@ -843,7 +843,10 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
cfg->voltages |= host->voltages;
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
if (caps & SDHCI_CAN_DO_HISPD)
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
cfg->host_caps |= MMC_MODE_4BIT;
/* Since Host Controller Version3.0 */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {

View File

@@ -276,7 +276,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
return PTR_ERR(priv->host->ioaddr);
priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
priv->bank = dev_read_u32_default(dev, "xlnx,mio_bank", -1);
priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0);
return 0;
}

View File

@@ -519,7 +519,7 @@ config TULIP
This driver supports DEC DC2114x Fast ethernet chips.
config XILINX_AXIEMAC
depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
depends on DM_ETH
select PHYLIB
select MII
bool "Xilinx AXI Ethernet"
@@ -527,7 +527,7 @@ config XILINX_AXIEMAC
This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
config XILINX_EMACLITE
depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP || MIPS)
depends on DM_ETH
select PHYLIB
select MII
bool "Xilinx Ethernetlite"
@@ -535,7 +535,7 @@ config XILINX_EMACLITE
This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
config ZYNQ_GEM
depends on DM_ETH && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL)
depends on DM_ETH
select PHYLIB
bool "Xilinx Ethernet GEM"
help