From 677a24cbc3ef47bef355df45eff289d2dc371df0 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti Date: Tue, 6 Jul 2021 20:43:01 -0300 Subject: [PATCH 01/19] xilinx: zynqmp: increase CONFIG_SYS_SPL_MALLOC_SIZE to 16MB commit 03f1f78a9b44 ("spl: fit: Prefer a malloc()'d buffer for loading images")' changed the way buffer allocation worked for SPL to a more flexible method. For xilinx zynqmp the 1MB buffer is not necessarily enough when dealing with complex fit images (e.g. containing FPGA/TF-A/OP-TEE/U-Boot proper), which can easily reach up to 10MB, so increase the default CONFIG_SYS_SPL_MALLOC_SIZE size to 16MB to cover more advanced scenarios. Signed-off-by: Ricardo Salveti Signed-off-by: Michal Simek --- include/configs/xilinx_zynqmp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index cadaf1a963..bfe8a20427 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -261,7 +261,7 @@ #endif #define CONFIG_SYS_SPL_MALLOC_START 0x20000000 -#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x1000000 #ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE # error "Disable CONFIG_SPL_SYS_MALLOC_SIMPLE. Full malloc needs to be used" From 8e34aa00e971b41764d03b335941f5bf14f605ac Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 9 Jul 2021 05:53:39 -0600 Subject: [PATCH 02/19] mmc: zynq_sdhci: Resolve uninitialized return value set_phase() functions are not modifying the ret value and returning the same uninitialized ret, return 0 instead. Keep the return type as int to return errors when the tapdelay's are set via xilinx_pm_request() in future. Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung Signed-off-by: Michal Simek --- drivers/mmc/zynq_sdhci.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index b79c4021b6..5bad5cb9e7 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -183,7 +183,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) * * @host: Pointer to the sdhci_host structure. * @degrees: The clock phase shift between 0 - 359. - * Return: 0 on success and error value on error + * Return: 0 */ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, int degrees) @@ -191,7 +191,6 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev); struct mmc *mmc = (struct mmc *)host->mmc; u8 tap_delay, tap_max = 0; - int ret; int timing = mode2timing[mmc->selected_mode]; /* @@ -229,7 +228,7 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, arasan_zynqmp_set_tapdelay(priv->deviceid, 0, tap_delay); - return ret; + return 0; } /** @@ -239,7 +238,7 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, * * @host: Pointer to the sdhci_host structure. * @degrees: The clock phase shift between 0 - 359. - * Return: 0 on success and error value on error + * Return: 0 */ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, int degrees) @@ -247,7 +246,6 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev); struct mmc *mmc = (struct mmc *)host->mmc; u8 tap_delay, tap_max = 0; - int ret; int timing = mode2timing[mmc->selected_mode]; /* @@ -285,7 +283,7 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, arasan_zynqmp_set_tapdelay(priv->deviceid, tap_delay, 0); - return ret; + return 0; } /** @@ -295,14 +293,13 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, * * @host: Pointer to the sdhci_host structure. * @degrees The clock phase shift between 0 - 359. - * Return: 0 on success and error value on error + * Return: 0 */ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, int degrees) { struct mmc *mmc = (struct mmc *)host->mmc; u8 tap_delay, tap_max = 0; - int ret; int timing = mode2timing[mmc->selected_mode]; /* @@ -349,7 +346,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); } - return ret; + return 0; } /** @@ -359,14 +356,13 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, * * @host: Pointer to the sdhci_host structure. * @degrees The clock phase shift between 0 - 359. - * Return: 0 on success and error value on error + * Return: 0 */ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, int degrees) { struct mmc *mmc = (struct mmc *)host->mmc; u8 tap_delay, tap_max = 0; - int ret; int timing = mode2timing[mmc->selected_mode]; /* @@ -417,7 +413,7 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); } - return ret; + return 0; } static void arasan_sdhci_set_tapdelay(struct sdhci_host *host) From affcba728b90428f38e6ea6b945935146c8f3dcb Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 9 Jul 2021 05:53:40 -0600 Subject: [PATCH 03/19] mmc: zynq_sdhci: Allow configuring zero Tap values Allow configuring ITAP and OTAP values with zero to avoid failures in some cases (one of them is SD boot mode). Legacy, SDR12 modes require to program the ITAP and OTAP values as zero, whereas for SDR50 and SDR104 modes ITAP value is zero. In SD boot mode firmware configures the SD ITAP and OTAP values and in this case u-boot has to re-configure required tap values(including zero) based on the operating mode. Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung Signed-off-by: Michal Simek --- drivers/mmc/zynq_sdhci.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 5bad5cb9e7..f65a87a4e1 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -198,9 +198,7 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, * ZynqMP does not set phase for <=25MHz clock. * If degrees is zero, no need to do anything. */ - if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 || - timing == MMC_TIMING_LEGACY || - timing == MMC_TIMING_UHS_SDR12 || !degrees) + if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) return 0; switch (timing) { @@ -253,9 +251,7 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, * ZynqMP does not set phase for <=25MHz clock. * If degrees is zero, no need to do anything. */ - if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 || - timing == MMC_TIMING_LEGACY || - timing == MMC_TIMING_UHS_SDR12 || !degrees) + if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) return 0; switch (timing) { @@ -307,9 +303,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, * Versal does not set phase for <=25MHz clock. * If degrees is zero, no need to do anything. */ - if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 || - timing == MMC_TIMING_LEGACY || - timing == MMC_TIMING_UHS_SDR12 || !degrees) + if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) return 0; switch (timing) { @@ -370,9 +364,7 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, * Versal does not set phase for <=25MHz clock. * If degrees is zero, no need to do anything. */ - if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 || - timing == MMC_TIMING_LEGACY || - timing == MMC_TIMING_UHS_SDR12 || !degrees) + if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) return 0; switch (timing) { From ee9ae005dc4cbd0a9a792c0b78385055f18b9a8a Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 9 Jul 2021 05:53:41 -0600 Subject: [PATCH 04/19] mmc: zynq_sdhci: Use Mask writes for Tap delays Restrict tap_delay value to the allowed size(8bits for itap and 6 bits for otap) before writing to the tap delay register. Clear ITAP and OTAP delay bits before updating with the new tap value for Versal platform. Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung Signed-off-by: Michal Simek --- drivers/mmc/zynq_sdhci.c | 58 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index f65a87a4e1..bf638e9675 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -19,11 +19,13 @@ #include #include -#define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 -#define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC -#define SDHCI_ITAPDLY_CHGWIN 0x200 -#define SDHCI_ITAPDLY_ENABLE 0x100 -#define SDHCI_OTAPDLY_ENABLE 0x40 +#define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 +#define SDHCI_ARASAN_ITAPDLY_SEL_MASK GENMASK(7, 0) +#define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC +#define SDHCI_ARASAN_OTAPDLY_SEL_MASK GENMASK(5, 0) +#define SDHCI_ITAPDLY_CHGWIN BIT(9) +#define SDHCI_ITAPDLY_ENABLE BIT(8) +#define SDHCI_OTAPDLY_ENABLE BIT(6) #define SDHCI_TUNING_LOOP_COUNT 40 #define MMC_BANK2 0x2 @@ -297,6 +299,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, struct mmc *mmc = (struct mmc *)host->mmc; u8 tap_delay, tap_max = 0; int timing = mode2timing[mmc->selected_mode]; + u32 regval; /* * This is applicable for SDHCI_SPEC_300 and above @@ -329,16 +332,16 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, tap_delay = (degrees * tap_max) / 360; - /* Set the Clock Phase */ - if (tap_delay) { - u32 regval; + /* Limit output tap_delay value to 6 bits */ + tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK; - regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); - regval |= SDHCI_OTAPDLY_ENABLE; - sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); - regval |= tap_delay; - sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); - } + /* Set the Clock Phase */ + regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); + regval |= SDHCI_OTAPDLY_ENABLE; + sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); + regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK; + regval |= tap_delay; + sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); return 0; } @@ -358,6 +361,7 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, struct mmc *mmc = (struct mmc *)host->mmc; u8 tap_delay, tap_max = 0; int timing = mode2timing[mmc->selected_mode]; + u32 regval; /* * This is applicable for SDHCI_SPEC_300 and above @@ -390,20 +394,20 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, tap_delay = (degrees * tap_max) / 360; - /* Set the Clock Phase */ - if (tap_delay) { - u32 regval; + /* Limit input tap_delay value to 8 bits */ + tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK; - regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER); - regval |= SDHCI_ITAPDLY_CHGWIN; - sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); - regval |= SDHCI_ITAPDLY_ENABLE; - sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); - regval |= tap_delay; - sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); - regval &= ~SDHCI_ITAPDLY_CHGWIN; - sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); - } + /* Set the Clock Phase */ + regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER); + regval |= SDHCI_ITAPDLY_CHGWIN; + sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); + regval |= SDHCI_ITAPDLY_ENABLE; + sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); + regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK; + regval |= tap_delay; + sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); + regval &= ~SDHCI_ITAPDLY_CHGWIN; + sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); return 0; } From a70bdafd67afa8d5a5ec73280c74a51a03640b66 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 9 Jul 2021 05:53:42 -0600 Subject: [PATCH 05/19] mmc: zynq_sdhci: Split set_tapdelay function to in and out Split arasan_zynqmp_set_tapdelay() to handle input and output tapdelays separately. This is required to handle zero values for ITAP and OTAP values. If we dont split, we will have to remove the if() in the function, which makes ITAP values to be overwritten when OTAP values are called to set and vice-versa. Restrict tap_delay value calculated to max allowed 8 bits for ITAP and 6 bits for OTAP for ZynqMP. Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung Signed-off-by: Michal Simek --- board/xilinx/zynqmp/tap_delays.c | 73 +++++++++++++++++--------------- drivers/mmc/zynq_sdhci.c | 10 ++++- include/zynqmp_tap_delay.h | 7 +-- 3 files changed, 50 insertions(+), 40 deletions(-) diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c index 1cab25f00a..d16bbb8eff 100644 --- a/board/xilinx/zynqmp/tap_delays.c +++ b/board/xilinx/zynqmp/tap_delays.c @@ -50,48 +50,51 @@ void zynqmp_dll_reset(u8 deviceid) zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); } -void arasan_zynqmp_set_tapdelay(u8 deviceid, u32 itap_delay, u32 otap_delay) +void arasan_zynqmp_set_in_tapdelay(u8 deviceid, u32 itap_delay) { if (deviceid == 0) { - zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, - SD0_DLL_RST); - /* Program ITAP */ - if (itap_delay) { - zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, - SD0_ITAPCHGWIN); - zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK, - SD0_ITAPDLYENA); - zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, - itap_delay); - zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, - 0x0); - } + zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST); - /* Program OTAP */ - if (otap_delay) - zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, - otap_delay); + /* Program ITAP delay */ + zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, + SD0_ITAPCHGWIN); + zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK, + SD0_ITAPDLYENA); + zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, itap_delay); + zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0); zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0); } else { - zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, - SD1_DLL_RST); - /* Program ITAP */ - if (itap_delay) { - zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, - SD1_ITAPCHGWIN); - zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK, - SD1_ITAPDLYENA); - zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK, - (itap_delay << 16)); - zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, - 0x0); - } + zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST); - /* Program OTAP */ - if (otap_delay) - zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, - (otap_delay << 16)); + /* Program ITAP delay */ + zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, + SD1_ITAPCHGWIN); + zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK, + SD1_ITAPDLYENA); + zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK, + (itap_delay << 16)); + zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0); + + zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); + } +} + +void arasan_zynqmp_set_out_tapdelay(u8 deviceid, u32 otap_delay) +{ + if (deviceid == 0) { + zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST); + + /* Program OTAP delay */ + zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, otap_delay); + + zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0); + } else { + zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST); + + /* Program OTAP delay */ + zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, + (otap_delay << 16)); zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); } diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index bf638e9675..95d42ccef4 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -226,7 +226,10 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, tap_delay = (degrees * tap_max) / 360; - arasan_zynqmp_set_tapdelay(priv->deviceid, 0, tap_delay); + /* Limit output tap_delay value to 6 bits */ + tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK; + + arasan_zynqmp_set_out_tapdelay(priv->deviceid, tap_delay); return 0; } @@ -279,7 +282,10 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, tap_delay = (degrees * tap_max) / 360; - arasan_zynqmp_set_tapdelay(priv->deviceid, tap_delay, 0); + /* Limit input tap_delay value to 8 bits */ + tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK; + + arasan_zynqmp_set_in_tapdelay(priv->deviceid, tap_delay); return 0; } diff --git a/include/zynqmp_tap_delay.h b/include/zynqmp_tap_delay.h index 7b713438f7..1c1e3e7dee 100644 --- a/include/zynqmp_tap_delay.h +++ b/include/zynqmp_tap_delay.h @@ -10,11 +10,12 @@ #ifdef CONFIG_ARCH_ZYNQMP void zynqmp_dll_reset(u8 deviceid); -void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay, u32 otap_delay); +void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay); +void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay); #else inline void zynqmp_dll_reset(u8 deviceid) {} -inline void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay, - u32 otap_delay) {} +inline void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay) {} +inline void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay) {} #endif #endif From c0436fcf1a5af15e5035cea71e39d3610fdecc35 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 9 Jul 2021 05:53:43 -0600 Subject: [PATCH 06/19] mmc: zynq_sdhci: Fix kernel doc warnings Fix these kernel doc warnings: drivers/mmc/zynq_sdhci.c:181: warning: contents before sections drivers/mmc/zynq_sdhci.c:236: warning: contents before sections drivers/mmc/zynq_sdhci.c:291: warning: contents before sections drivers/mmc/zynq_sdhci.c:297: warning: Function parameter or member 'degrees' not described in 'sdhci_versal_sdcardclk_set_phase' drivers/mmc/zynq_sdhci.c:354: warning: contents before sections drivers/mmc/zynq_sdhci.c:360: warning: Function parameter or member 'degrees' not described in 'sdhci_versal_sampleclk_set_phase' drivers/mmc/zynq_sdhci.c:467: warning: contents before sections Signed-off-by: Michal Simek Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung --- drivers/mmc/zynq_sdhci.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 95d42ccef4..47862c0bf5 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -181,11 +181,11 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) /** * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays * - * Set the SD Output Clock Tap Delays for Output path - * * @host: Pointer to the sdhci_host structure. * @degrees: The clock phase shift between 0 - 359. * Return: 0 + * + * Set the SD Output Clock Tap Delays for Output path */ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, int degrees) @@ -237,11 +237,11 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, /** * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays * - * Set the SD Input Clock Tap Delays for Input path - * * @host: Pointer to the sdhci_host structure. * @degrees: The clock phase shift between 0 - 359. * Return: 0 + * + * Set the SD Input Clock Tap Delays for Input path */ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, int degrees) @@ -293,11 +293,11 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, /** * sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays * - * Set the SD Output Clock Tap Delays for Output path - * * @host: Pointer to the sdhci_host structure. - * @degrees The clock phase shift between 0 - 359. + * @degrees: The clock phase shift between 0 - 359. * Return: 0 + * + * Set the SD Output Clock Tap Delays for Output path */ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, int degrees) @@ -355,11 +355,11 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, /** * sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays * - * Set the SD Input Clock Tap Delays for Input path - * * @host: Pointer to the sdhci_host structure. - * @degrees The clock phase shift between 0 - 359. + * @degrees: The clock phase shift between 0 - 359. * Return: 0 + * + * Set the SD Input Clock Tap Delays for Input path */ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, int degrees) @@ -467,9 +467,9 @@ static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing, /** * arasan_dt_parse_clk_phases - Read Tap Delay values from DT * - * Called at initialization to parse the values of Tap Delays. - * * @dev: Pointer to our struct udevice. + * + * Called at initialization to parse the values of Tap Delays. */ static void arasan_dt_parse_clk_phases(struct udevice *dev) { From 419b4a86f784c819c520d88658799cb71063f87e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 9 Jul 2021 05:53:44 -0600 Subject: [PATCH 07/19] mmc: zynq_sdhci: Make variables/structure static All these variables/structure are local and should be static. Issues are reported by sparse: drivers/mmc/zynq_sdhci.c:49:11: warning: symbol 'zynqmp_iclk_phases' was not declared. Should it be static? drivers/mmc/zynq_sdhci.c:50:11: warning: symbol 'zynqmp_oclk_phases' was not declared. Should it be static? drivers/mmc/zynq_sdhci.c:53:11: warning: symbol 'versal_iclk_phases' was not declared. Should it be static? drivers/mmc/zynq_sdhci.c:54:11: warning: symbol 'versal_oclk_phases' was not declared. Should it be static? drivers/mmc/zynq_sdhci.c:546:24: warning: symbol 'arasan_ops' was not declared. Should it be static? Signed-off-by: Michal Simek Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung --- drivers/mmc/zynq_sdhci.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 47862c0bf5..ba87ee8dd5 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -50,12 +50,16 @@ struct arasan_sdhci_priv { #if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) /* Default settings for ZynqMP Clock Phases */ -const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0}; -const u32 zynqmp_oclk_phases[] = {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0}; +static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0, + 0, 183, 54, 0, 0}; +static const u32 zynqmp_oclk_phases[] = {0, 72, 60, 0, 60, 72, + 135, 48, 72, 135, 0}; /* Default settings for Versal Clock Phases */ -const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0}; -const u32 versal_oclk_phases[] = {0, 60, 48, 0, 48, 72, 90, 36, 60, 90, 0}; +static const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132, + 0, 0, 162, 90, 0, 0}; +static const u32 versal_oclk_phases[] = {0, 60, 48, 0, 48, 72, + 90, 36, 60, 90, 0}; static const u8 mode2timing[] = { [MMC_LEGACY] = MMC_TIMING_LEGACY, @@ -541,8 +545,8 @@ static void arasan_sdhci_set_control_reg(struct sdhci_host *host) sdhci_set_uhs_timing(host); } -const struct sdhci_ops arasan_ops = { - .platform_execute_tuning = &arasan_sdhci_execute_tuning, +static const struct sdhci_ops arasan_ops = { + .platform_execute_tuning = &arasan_sdhci_execute_tuning, .set_delay = &arasan_sdhci_set_tapdelay, .set_control_reg = &arasan_sdhci_set_control_reg, }; From 50918d0df5cb23a1751d8443f352726a582c9c76 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Fri, 2 Jul 2021 10:28:36 +0200 Subject: [PATCH 08/19] xilinx: Return ENVL_NOWHERE instead of ENVL_UNKNOWN The system refuses to boot without any environment, so return ENVL_NOWHERE when there's nowhere to store the environment instead of ENVL_UNKNOWN. This fixes that the board won't boot from eMMC when CONFIG_ENV_IS_IN_FAT is not defined, for example. Similar for other combinations. Fixes: 1025bd098aa8 "xilinx: zynqmp: Add support for saving variables" Signed-off-by: Mike Looijmans Signed-off-by: Michal Simek --- board/xilinx/zynq/board.c | 6 +++--- board/xilinx/zynqmp/zynqmp.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index e2e9b3f0f7..61e0a90c11 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -134,18 +134,18 @@ enum env_location env_get_location(enum env_operation op, int prio) return ENVL_FAT; if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) return ENVL_EXT4; - return ENVL_UNKNOWN; + return ENVL_NOWHERE; case ZYNQ_BM_NAND: if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND)) return ENVL_NAND; if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI)) return ENVL_UBI; - return ENVL_UNKNOWN; + return ENVL_NOWHERE; case ZYNQ_BM_NOR: case ZYNQ_BM_QSPI: if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) return ENVL_SPI_FLASH; - return ENVL_UNKNOWN; + return ENVL_NOWHERE; case ZYNQ_BM_JTAG: default: return ENVL_NOWHERE; diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 1748fec2e4..18d5c515de 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -797,18 +797,18 @@ enum env_location env_get_location(enum env_operation op, int prio) return ENVL_FAT; if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) return ENVL_EXT4; - return ENVL_UNKNOWN; + return ENVL_NOWHERE; case NAND_MODE: if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND)) return ENVL_NAND; if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI)) return ENVL_UBI; - return ENVL_UNKNOWN; + return ENVL_NOWHERE; case QSPI_MODE_24BIT: case QSPI_MODE_32BIT: if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) return ENVL_SPI_FLASH; - return ENVL_UNKNOWN; + return ENVL_NOWHERE; case JTAG_MODE: default: return ENVL_NOWHERE; From d036f4f2c6ee4dbddea67ad9bd5f8686b1f2d427 Mon Sep 17 00:00:00 2001 From: Piyush Mehta Date: Sat, 3 Jul 2021 10:40:30 +0530 Subject: [PATCH 09/19] arm64: dts: zynqmp: Enable USB2.0 for zc1751-xm016-dc2 The board zynqmp-zc1751-xm016-dc2 support only USB2.0. This patch removes USB3.0 DT configuration for DC2 board. Signed-off-by: Piyush Mehta Signed-off-by: Michal Simek --- arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts index 5b689dbd09..4225a9547c 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts @@ -535,8 +535,6 @@ &dwc3_1 { status = "okay"; dr_mode = "host"; - snps,usb3_lpm_capable; - maximum-speed = "super-speed"; }; &uart0 { From 0c383a79577b95e745abe466fab5fd744887dec8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 1 Jul 2021 19:01:42 +0200 Subject: [PATCH 10/19] clk: zynqmp: Add support for enabling clock on lpd_lsbus lpd_lsbus is clock which is used by many IPs like dmas, gems, gpio, sdhcis, spis, ttcs, uarts, watchdog that's why make sense to also enable access to change this clock. For this clock you already get the rate. Signed-off-by: Michal Simek --- drivers/clk/clk_zynqmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index 13a623fdb9..52fecec7a7 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -813,6 +813,7 @@ static int zynqmp_clk_enable(struct clk *clk) mask = 0x3; break; case qspi_ref ... can1_ref: + case lpd_lsbus: clkact_shift = 24; mask = 0x1; break; From d20cf6b6c3ff15ff497bd96882b28616048b35eb Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 2 Jul 2021 04:40:33 -0600 Subject: [PATCH 11/19] net: ethtool: Add ethernet speed macros for higher speeds Add speed macro's for higher ethernet speeds to be used in u-boot networking drivers. Added Macros for speeds 14G, 20G, 25G, 40G, 50G, 56G, 100G and 200G inline with linux. Signed-off-by: Ashok Reddy Soma Reviewed-by: Simon Glass Acked-by: Ramon Fried Signed-off-by: Michal Simek --- include/linux/ethtool.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index f6dbdb096d..aa7d2fd58f 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -620,6 +620,14 @@ enum ethtool_sfeatures_retval_bits { #define SPEED_1000 1000 #define SPEED_2500 2500 #define SPEED_10000 10000 +#define SPEED_14000 14000 +#define SPEED_20000 20000 +#define SPEED_25000 25000 +#define SPEED_40000 40000 +#define SPEED_50000 50000 +#define SPEED_56000 56000 +#define SPEED_100000 100000 +#define SPEED_200000 200000 /* Duplex, half or full. */ #define DUPLEX_HALF 0x00 From 258ce79cfce4b17b4afe867353c0365cc3c26b46 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 2 Jul 2021 04:40:34 -0600 Subject: [PATCH 12/19] net: xilinx: axi_mrmac: Add MRMAC driver Add support for xilinx multirate(MRMAC) ethernet driver. This driver uses multichannel DMA(MCDMA) for data transfers of MRMAC. Added support for 4 ports of MRMAC for speeds 10G and 25G. MCDMA supports upto 16 channels but in this driver we have setup only one channel which is enough. Tested 10G and 25G on all 4 ports. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek --- MAINTAINERS | 1 + drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/xilinx_axi_mrmac.c | 564 +++++++++++++++++++++++++++++++++ drivers/net/xilinx_axi_mrmac.h | 203 ++++++++++++ 5 files changed, 778 insertions(+) create mode 100644 drivers/net/xilinx_axi_mrmac.c create mode 100644 drivers/net/xilinx_axi_mrmac.h diff --git a/MAINTAINERS b/MAINTAINERS index ae6c70860d..8a18b3b6d9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -545,6 +545,7 @@ M: Michal Simek S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git F: arch/arm/mach-versal/ +F: drivers/net/xilinx_axi_mrmac.* F: drivers/watchdog/xilinx_wwdt.c N: (? + * Michal Simek + * + * Copyright (C) 2021 Xilinx, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xilinx_axi_mrmac.h" + +static void axi_mrmac_dma_write(struct mcdma_bd *bd, u32 *desc) +{ + if (IS_ENABLED(CONFIG_PHYS_64BIT)) + writeq((unsigned long)bd, desc); + else + writel((uintptr_t)bd, desc); +} + +/** + * axi_mrmac_ethernet_init - MRMAC init function + * @priv: MRMAC private structure + * + * Return: 0 on success, negative value on errors + * + * This function is called to reset and initialize MRMAC core. This is + * typically called during initialization. It does a reset of MRMAC Rx/Tx + * channels and Rx/Tx SERDES. It configures MRMAC speed based on mrmac_rate + * which is read from DT. This function waits for block lock bit to get set, + * if it is not set within 100ms time returns a timeout error. + */ +static int axi_mrmac_ethernet_init(struct axi_mrmac_priv *priv) +{ + struct mrmac_regs *regs = priv->iobase; + u32 reg; + u32 ret; + + /* Perform all the RESET's required */ + setbits_le32(®s->reset, MRMAC_RX_SERDES_RST_MASK | MRMAC_RX_RST_MASK + | MRMAC_TX_SERDES_RST_MASK | MRMAC_TX_RST_MASK); + + mdelay(MRMAC_RESET_DELAY); + + /* Configure Mode register */ + reg = readl(®s->mode); + + log_debug("Configuring MRMAC speed to %d\n", priv->mrmac_rate); + + if (priv->mrmac_rate == SPEED_25000) { + reg &= ~MRMAC_CTL_RATE_CFG_MASK; + reg |= MRMAC_CTL_DATA_RATE_25G; + reg |= (MRMAC_CTL_AXIS_CFG_25G_IND << MRMAC_CTL_AXIS_CFG_SHIFT); + reg |= (MRMAC_CTL_SERDES_WIDTH_25G << + MRMAC_CTL_SERDES_WIDTH_SHIFT); + } else { + reg &= ~MRMAC_CTL_RATE_CFG_MASK; + reg |= MRMAC_CTL_DATA_RATE_10G; + reg |= (MRMAC_CTL_AXIS_CFG_10G_IND << MRMAC_CTL_AXIS_CFG_SHIFT); + reg |= (MRMAC_CTL_SERDES_WIDTH_10G << + MRMAC_CTL_SERDES_WIDTH_SHIFT); + } + + /* For tick reg */ + reg |= MRMAC_CTL_PM_TICK_MASK; + writel(reg, ®s->mode); + + clrbits_le32(®s->reset, MRMAC_RX_SERDES_RST_MASK | MRMAC_RX_RST_MASK + | MRMAC_TX_SERDES_RST_MASK | MRMAC_TX_RST_MASK); + + mdelay(MRMAC_RESET_DELAY); + + /* Setup MRMAC hardware options */ + setbits_le32(®s->rx_config, MRMAC_RX_DEL_FCS_MASK); + setbits_le32(®s->tx_config, MRMAC_TX_INS_FCS_MASK); + setbits_le32(®s->tx_config, MRMAC_TX_EN_MASK); + setbits_le32(®s->rx_config, MRMAC_RX_EN_MASK); + + /* Check for block lock bit to be set. This ensures that + * MRMAC ethernet IP is functioning normally. + */ + writel(MRMAC_STS_ALL_MASK, (phys_addr_t)priv->iobase + + MRMAC_TX_STS_OFFSET); + writel(MRMAC_STS_ALL_MASK, (phys_addr_t)priv->iobase + + MRMAC_RX_STS_OFFSET); + writel(MRMAC_STS_ALL_MASK, (phys_addr_t)priv->iobase + + MRMAC_STATRX_BLKLCK_OFFSET); + + ret = wait_for_bit_le32((u32 *)((phys_addr_t)priv->iobase + + MRMAC_STATRX_BLKLCK_OFFSET), + MRMAC_RX_BLKLCK_MASK, true, + MRMAC_BLKLCK_TIMEOUT, true); + if (ret) { + log_warning("Error: MRMAC block lock not complete!\n"); + return -EIO; + } + + writel(MRMAC_TICK_TRIGGER, ®s->tick_reg); + + return 0; +} + +/** + * axi_mcdma_init - Reset MCDMA engine + * @priv: MRMAC private structure + * + * Return: 0 on success, negative value on timeouts + * + * This function is called to reset and initialize MCDMA engine + */ +static int axi_mcdma_init(struct axi_mrmac_priv *priv) +{ + u32 ret; + + /* Reset the engine so the hardware starts from a known state */ + writel(XMCDMA_CR_RESET, &priv->mm2s_cmn->control); + writel(XMCDMA_CR_RESET, &priv->s2mm_cmn->control); + + /* Check Tx/Rx MCDMA.RST. Reset is done when the reset bit is low */ + ret = wait_for_bit_le32(&priv->mm2s_cmn->control, XMCDMA_CR_RESET, + false, MRMAC_DMARST_TIMEOUT, true); + if (ret) { + log_warning("Tx MCDMA reset Timeout\n"); + return -ETIMEDOUT; + } + + ret = wait_for_bit_le32(&priv->s2mm_cmn->control, XMCDMA_CR_RESET, + false, MRMAC_DMARST_TIMEOUT, true); + if (ret) { + log_warning("Rx MCDMA reset Timeout\n"); + return -ETIMEDOUT; + } + + /* Enable channel 1 for Tx and Rx */ + writel(XMCDMA_CHANNEL_1, &priv->mm2s_cmn->chen); + writel(XMCDMA_CHANNEL_1, &priv->s2mm_cmn->chen); + + return 0; +} + +/** + * axi_mrmac_start - MRMAC start + * @dev: udevice structure + * + * Return: 0 on success, negative value on errors + * + * This is a initialization function of MRMAC. Call MCDMA initialization + * function and setup Rx buffer descriptors for starting reception of packets. + * Enable Tx and Rx channels and trigger Rx channel fetch. + */ +static int axi_mrmac_start(struct udevice *dev) +{ + struct axi_mrmac_priv *priv = dev_get_priv(dev); + struct mrmac_regs *regs = priv->iobase; + + /* + * Initialize MCDMA engine. MCDMA engine must be initialized before + * MRMAC. During MCDMA engine initialization, MCDMA hardware is reset, + * since MCDMA reset line is connected to MRMAC, this would ensure a + * reset of MRMAC. + */ + axi_mcdma_init(priv); + + /* Initialize MRMAC hardware */ + if (axi_mrmac_ethernet_init(priv)) + return -EIO; + + /* Disable all Rx interrupts before RxBD space setup */ + clrbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK); + + /* Update current descriptor */ + axi_mrmac_dma_write(priv->rx_bd[0], &priv->mcdma_rx->current); + + /* Setup Rx BD. MRMAC needs atleast two descriptors */ + memset(priv->rx_bd[0], 0, RX_BD_TOTAL_SIZE); + + priv->rx_bd[0]->next_desc = lower_32_bits((u64)priv->rx_bd[1]); + priv->rx_bd[0]->buf_addr = lower_32_bits((u64)net_rx_packets[0]); + + priv->rx_bd[1]->next_desc = lower_32_bits((u64)priv->rx_bd[0]); + priv->rx_bd[1]->buf_addr = lower_32_bits((u64)net_rx_packets[1]); + + if (IS_ENABLED(CONFIG_PHYS_64BIT)) { + priv->rx_bd[0]->next_desc_msb = upper_32_bits((u64)priv->rx_bd[1]); + priv->rx_bd[0]->buf_addr_msb = upper_32_bits((u64)net_rx_packets[0]); + + priv->rx_bd[1]->next_desc_msb = upper_32_bits((u64)priv->rx_bd[0]); + priv->rx_bd[1]->buf_addr_msb = upper_32_bits((u64)net_rx_packets[1]); + } + + priv->rx_bd[0]->cntrl = PKTSIZE_ALIGN; + priv->rx_bd[1]->cntrl = PKTSIZE_ALIGN; + + /* Flush the last BD so DMA core could see the updates */ + flush_cache((phys_addr_t)priv->rx_bd[0], RX_BD_TOTAL_SIZE); + + /* It is necessary to flush rx buffers because if you don't do it + * then cache can contain uninitialized data + */ + flush_cache((phys_addr_t)priv->rx_bd[0]->buf_addr, RX_BUFF_TOTAL_SIZE); + + /* Start the hardware */ + setbits_le32(&priv->s2mm_cmn->control, XMCDMA_CR_RUNSTOP_MASK); + setbits_le32(&priv->mm2s_cmn->control, XMCDMA_CR_RUNSTOP_MASK); + setbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK); + + /* Channel fetch */ + setbits_le32(&priv->mcdma_rx->control, XMCDMA_CR_RUNSTOP_MASK); + + /* Update tail descriptor. Now it's ready to receive data */ + axi_mrmac_dma_write(priv->rx_bd[1], &priv->mcdma_rx->tail); + + /* Enable Tx */ + setbits_le32(®s->tx_config, MRMAC_TX_EN_MASK); + + /* Enable Rx */ + setbits_le32(®s->rx_config, MRMAC_RX_EN_MASK); + + return 0; +} + +/** + * axi_mrmac_send - MRMAC Tx function + * @dev: udevice structure + * @ptr: pointer to Tx buffer + * @len: transfer length + * + * Return: 0 on success, negative value on errors + * + * This is a Tx send function of MRMAC. Setup Tx buffer descriptors and trigger + * transfer. Wait till the data is transferred. + */ +static int axi_mrmac_send(struct udevice *dev, void *ptr, int len) +{ + struct axi_mrmac_priv *priv = dev_get_priv(dev); + u32 ret; + +#ifdef DEBUG + print_buffer(ptr, ptr, 1, len, 16); +#endif + if (len > PKTSIZE_ALIGN) + len = PKTSIZE_ALIGN; + + /* If size is less than min packet size, pad to min size */ + if (len < MIN_PKT_SIZE) { + memset(priv->txminframe, 0, MIN_PKT_SIZE); + memcpy(priv->txminframe, ptr, len); + len = MIN_PKT_SIZE; + ptr = priv->txminframe; + } + + writel(XMCDMA_IRQ_ALL_MASK, &priv->mcdma_tx->status); + + clrbits_le32(&priv->mcdma_tx->control, XMCDMA_CR_RUNSTOP_MASK); + + /* Flush packet to main memory to be trasfered by DMA */ + flush_cache((phys_addr_t)ptr, len); + + /* Setup Tx BD. MRMAC needs atleast two descriptors */ + memset(priv->tx_bd[0], 0, TX_BD_TOTAL_SIZE); + + priv->tx_bd[0]->next_desc = lower_32_bits((u64)priv->tx_bd[1]); + priv->tx_bd[0]->buf_addr = lower_32_bits((u64)ptr); + + /* At the end of the ring, link the last BD back to the top */ + priv->tx_bd[1]->next_desc = lower_32_bits((u64)priv->tx_bd[0]); + priv->tx_bd[1]->buf_addr = lower_32_bits((u64)ptr + len / 2); + + if (IS_ENABLED(CONFIG_PHYS_64BIT)) { + priv->tx_bd[0]->next_desc_msb = upper_32_bits((u64)priv->tx_bd[1]); + priv->tx_bd[0]->buf_addr_msb = upper_32_bits((u64)ptr); + + priv->tx_bd[1]->next_desc_msb = upper_32_bits((u64)priv->tx_bd[0]); + priv->tx_bd[1]->buf_addr_msb = upper_32_bits((u64)ptr + len / 2); + } + + /* Split Tx data in to half and send in two descriptors */ + priv->tx_bd[0]->cntrl = (len / 2) | XMCDMA_BD_CTRL_TXSOF_MASK; + priv->tx_bd[1]->cntrl = (len - len / 2) | XMCDMA_BD_CTRL_TXEOF_MASK; + + /* Flush the last BD so DMA core could see the updates */ + flush_cache((phys_addr_t)priv->tx_bd[0], TX_BD_TOTAL_SIZE); + + if (readl(&priv->mcdma_tx->status) & XMCDMA_CH_IDLE) { + axi_mrmac_dma_write(priv->tx_bd[0], &priv->mcdma_tx->current); + /* Channel fetch */ + setbits_le32(&priv->mcdma_tx->control, XMCDMA_CR_RUNSTOP_MASK); + } else { + log_warning("Error: current desc is not updated\n"); + return -EIO; + } + + setbits_le32(&priv->mcdma_tx->control, XMCDMA_IRQ_ALL_MASK); + + /* Start transfer */ + axi_mrmac_dma_write(priv->tx_bd[1], &priv->mcdma_tx->tail); + + /* Wait for transmission to complete */ + ret = wait_for_bit_le32(&priv->mcdma_tx->status, XMCDMA_IRQ_IOC_MASK, + true, 1, true); + if (ret) { + log_warning("%s: Timeout\n", __func__); + return -ETIMEDOUT; + } + + /* Clear status */ + priv->tx_bd[0]->sband_stats = 0; + priv->tx_bd[1]->sband_stats = 0; + + log_debug("Sending complete\n"); + + return 0; +} + +static bool isrxready(struct axi_mrmac_priv *priv) +{ + u32 status; + + /* Read pending interrupts */ + status = readl(&priv->mcdma_rx->status); + + /* Acknowledge pending interrupts */ + writel(status & XMCDMA_IRQ_ALL_MASK, &priv->mcdma_rx->status); + + /* + * If Reception done interrupt is asserted, call Rx call back function + * to handle the processed BDs and then raise the according flag. + */ + if (status & (XMCDMA_IRQ_IOC_MASK | XMCDMA_IRQ_DELAY_MASK)) + return 1; + + return 0; +} + +/** + * axi_mrmac_recv - MRMAC Rx function + * @dev: udevice structure + * @flags: flags from network stack + * @packetp pointer to received data + * + * Return: received data length on success, negative value on errors + * + * This is a Rx function of MRMAC. Check if any data is received on MCDMA. + * Copy buffer pointer to packetp and return received data length. + */ +static int axi_mrmac_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct axi_mrmac_priv *priv = dev_get_priv(dev); + u32 rx_bd_end; + u32 length; + + /* Wait for an incoming packet */ + if (!isrxready(priv)) + return -EAGAIN; + + /* Clear all interrupts */ + writel(XMCDMA_IRQ_ALL_MASK, &priv->mcdma_rx->status); + + /* Disable IRQ for a moment till packet is handled */ + clrbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK); + + /* Disable channel fetch */ + clrbits_le32(&priv->mcdma_rx->control, XMCDMA_CR_RUNSTOP_MASK); + + rx_bd_end = (ulong)priv->rx_bd[0] + roundup(RX_BD_TOTAL_SIZE, + ARCH_DMA_MINALIGN); + /* Invalidate Rx descriptors to see proper Rx length */ + invalidate_dcache_range((phys_addr_t)priv->rx_bd[0], rx_bd_end); + + length = priv->rx_bd[0]->status & XMCDMA_BD_STS_ACTUAL_LEN_MASK; + *packetp = (uchar *)(ulong)priv->rx_bd[0]->buf_addr; + + if (!length) { + length = priv->rx_bd[1]->status & XMCDMA_BD_STS_ACTUAL_LEN_MASK; + *packetp = (uchar *)(ulong)priv->rx_bd[1]->buf_addr; + } + +#ifdef DEBUG + print_buffer(*packetp, *packetp, 1, length, 16); +#endif + /* Clear status */ + priv->rx_bd[0]->status = 0; + priv->rx_bd[1]->status = 0; + + return length; +} + +/** + * axi_mrmac_free_pkt - MRMAC free packet function + * @dev: udevice structure + * @packet: receive buffer pointer + * @length received data length + * + * Return: 0 on success, negative value on errors + * + * This is Rx free packet function of MRMAC. Prepare MRMAC for reception of + * data again. Invalidate previous data from Rx buffers and set Rx buffer + * descriptors. Trigger reception by updating tail descriptor. + */ +static int axi_mrmac_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct axi_mrmac_priv *priv = dev_get_priv(dev); + +#ifdef DEBUG + /* It is useful to clear buffer to be sure that it is consistent */ + memset(priv->rx_bd[0]->buf_addr, 0, RX_BUFF_TOTAL_SIZE); +#endif + /* Disable all Rx interrupts before RxBD space setup */ + clrbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK); + + /* Disable channel fetch */ + clrbits_le32(&priv->mcdma_rx->control, XMCDMA_CR_RUNSTOP_MASK); + + /* Update current descriptor */ + axi_mrmac_dma_write(priv->rx_bd[0], &priv->mcdma_rx->current); + + /* Write bd to HW */ + flush_cache((phys_addr_t)priv->rx_bd[0], RX_BD_TOTAL_SIZE); + + /* It is necessary to flush rx buffers because if you don't do it + * then cache will contain previous packet + */ + flush_cache((phys_addr_t)priv->rx_bd[0]->buf_addr, RX_BUFF_TOTAL_SIZE); + + /* Enable all IRQ */ + setbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK); + + /* Channel fetch */ + setbits_le32(&priv->mcdma_rx->control, XMCDMA_CR_RUNSTOP_MASK); + + /* Update tail descriptor. Now it's ready to receive data */ + axi_mrmac_dma_write(priv->rx_bd[1], &priv->mcdma_rx->tail); + + log_debug("Rx completed, framelength = %x\n", length); + + return 0; +} + +/** + * axi_mrmac_stop - Stop MCDMA transfers + * @dev: udevice structure + * + * Return: 0 on success, negative value on errors + * + * Stop MCDMA engine for both Tx and Rx transfers. + */ +static void axi_mrmac_stop(struct udevice *dev) +{ + struct axi_mrmac_priv *priv = dev_get_priv(dev); + + /* Stop the hardware */ + clrbits_le32(&priv->mcdma_tx->control, XMCDMA_CR_RUNSTOP_MASK); + clrbits_le32(&priv->mcdma_rx->control, XMCDMA_CR_RUNSTOP_MASK); + + log_debug("Halted\n"); +} + +static int axi_mrmac_probe(struct udevice *dev) +{ + struct axi_mrmac_plat *plat = dev_get_plat(dev); + struct eth_pdata *pdata = &plat->eth_pdata; + struct axi_mrmac_priv *priv = dev_get_priv(dev); + + priv->iobase = (struct mrmac_regs *)pdata->iobase; + + priv->mm2s_cmn = plat->mm2s_cmn; + priv->mcdma_tx = (struct mcdma_chan_reg *)((phys_addr_t)priv->mm2s_cmn + + XMCDMA_CHAN_OFFSET); + priv->s2mm_cmn = (struct mcdma_common_regs *)((phys_addr_t)priv->mm2s_cmn + + XMCDMA_RX_OFFSET); + priv->mcdma_rx = (struct mcdma_chan_reg *)((phys_addr_t)priv->s2mm_cmn + + XMCDMA_CHAN_OFFSET); + priv->mrmac_rate = plat->mrmac_rate; + + /* Align buffers to ARCH_DMA_MINALIGN */ + priv->tx_bd[0] = memalign(ARCH_DMA_MINALIGN, TX_BD_TOTAL_SIZE); + priv->tx_bd[1] = (struct mcdma_bd *)((ulong)priv->tx_bd[0] + + sizeof(struct mcdma_bd)); + + priv->rx_bd[0] = memalign(ARCH_DMA_MINALIGN, RX_BD_TOTAL_SIZE); + priv->rx_bd[1] = (struct mcdma_bd *)((ulong)priv->rx_bd[0] + + sizeof(struct mcdma_bd)); + + priv->txminframe = memalign(ARCH_DMA_MINALIGN, MIN_PKT_SIZE); + + return 0; +} + +static int axi_mrmac_remove(struct udevice *dev) +{ + struct axi_mrmac_priv *priv = dev_get_priv(dev); + + /* Free buffer descriptors */ + free(priv->tx_bd[0]); + free(priv->rx_bd[0]); + free(priv->txminframe); + + return 0; +} + +static int axi_mrmac_of_to_plat(struct udevice *dev) +{ + struct axi_mrmac_plat *plat = dev_get_plat(dev); + struct eth_pdata *pdata = &plat->eth_pdata; + struct ofnode_phandle_args phandle_args; + int ret = 0; + + pdata->iobase = dev_read_addr(dev); + + ret = dev_read_phandle_with_args(dev, "axistream-connected", NULL, 0, 0, + &phandle_args); + if (ret) { + log_debug("axistream not found\n"); + return -EINVAL; + } + + plat->mm2s_cmn = (struct mcdma_common_regs *)ofnode_read_u64_default + (phandle_args.node, "reg", -1); + if (!plat->mm2s_cmn) { + log_warning("MRMAC dma register space not found\n"); + return -EINVAL; + } + + /* Set default MRMAC rate to 10000 */ + plat->mrmac_rate = dev_read_u32_default(dev, "xlnx,mrmac-rate", 10000); + + return 0; +} + +static const struct eth_ops axi_mrmac_ops = { + .start = axi_mrmac_start, + .send = axi_mrmac_send, + .recv = axi_mrmac_recv, + .free_pkt = axi_mrmac_free_pkt, + .stop = axi_mrmac_stop, +}; + +static const struct udevice_id axi_mrmac_ids[] = { + { .compatible = "xlnx,mrmac-ethernet-1.0" }, + { } +}; + +U_BOOT_DRIVER(axi_mrmac) = { + .name = "axi_mrmac", + .id = UCLASS_ETH, + .of_match = axi_mrmac_ids, + .of_to_plat = axi_mrmac_of_to_plat, + .probe = axi_mrmac_probe, + .remove = axi_mrmac_remove, + .ops = &axi_mrmac_ops, + .priv_auto = sizeof(struct axi_mrmac_priv), + .plat_auto = sizeof(struct axi_mrmac_plat), +}; diff --git a/drivers/net/xilinx_axi_mrmac.h b/drivers/net/xilinx_axi_mrmac.h new file mode 100644 index 0000000000..4f875857cf --- /dev/null +++ b/drivers/net/xilinx_axi_mrmac.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx Multirate Ethernet MAC(MRMAC) driver + * + * Author(s): Ashok Reddy Soma + * Michal Simek + * + * Copyright (C) 2021 Xilinx, Inc. All rights reserved. + */ + +#ifndef __XILINX_AXI_MRMAC_H +#define __XILINX_AXI_MRMAC_H + +#define MIN_PKT_SIZE 60 + +/* MRMAC needs atleast two buffer descriptors for Tx/Rx to work. + * Otherwise MRMAC will drop the packets. So, have atleast two Tx and + * two Rx bd's. + */ +#define TX_DESC 2 +#define RX_DESC 2 + +/* MRMAC platform data structure */ +struct axi_mrmac_plat { + struct eth_pdata eth_pdata; + struct mcdma_common_regs *mm2s_cmn; + u32 mrmac_rate; /* Hold the value from DT property "mrmac-rate" */ +}; + +/* MRMAC private driver structure */ +struct axi_mrmac_priv { + struct mrmac_regs *iobase; + struct mcdma_common_regs *mm2s_cmn; + struct mcdma_common_regs *s2mm_cmn; + struct mcdma_chan_reg *mcdma_tx; + struct mcdma_chan_reg *mcdma_rx; + struct mcdma_bd *tx_bd[TX_DESC]; + struct mcdma_bd *rx_bd[RX_DESC]; + u8 *txminframe; /* Pointer to hold min length Tx frame(60) */ + u32 mrmac_rate; /* Speed to configure(Read from DT 10G/25G..) */ +}; + +/* MRMAC Register Definitions */ +struct mrmac_regs { + u32 revision; /* 0x0: Revision Register */ + u32 reset; /* 0x4: Reset Register */ + u32 mode; /* 0x8: Mode */ + u32 tx_config; /* 0xc: Tx Configuration */ + u32 rx_config; /* 0x10: Rx Configuration */ + u32 reserved[6];/* 0x14-0x28: Reserved */ + u32 tick_reg; /* 0x2c: Tick Register */ +}; + +#define TX_BD_TOTAL_SIZE (TX_DESC * sizeof(struct mcdma_bd)) +#define RX_BD_TOTAL_SIZE (RX_DESC * sizeof(struct mcdma_bd)) + +#define RX_BUFF_TOTAL_SIZE (RX_DESC * PKTSIZE_ALIGN) + +/* Status Registers */ +#define MRMAC_TX_STS_OFFSET 0x740 +#define MRMAC_RX_STS_OFFSET 0x744 +#define MRMAC_TX_RT_STS_OFFSET 0x748 +#define MRMAC_RX_RT_STS_OFFSET 0x74c +#define MRMAC_STATRX_BLKLCK_OFFSET 0x754 + +/* Register bit masks */ +#define MRMAC_RX_SERDES_RST_MASK (BIT(3) | BIT(2) | BIT(1) | BIT(0)) +#define MRMAC_TX_SERDES_RST_MASK BIT(4) +#define MRMAC_RX_RST_MASK BIT(5) +#define MRMAC_TX_RST_MASK BIT(6) +#define MRMAC_RX_AXI_RST_MASK BIT(8) +#define MRMAC_TX_AXI_RST_MASK BIT(9) +#define MRMAC_STS_ALL_MASK 0xffffffff + +#define MRMAC_RX_EN_MASK BIT(0) +#define MRMAC_RX_DEL_FCS_MASK BIT(1) + +#define MRMAC_TX_EN_MASK BIT(0) +#define MRMAC_TX_INS_FCS_MASK BIT(1) + +#define MRMAC_RX_BLKLCK_MASK BIT(0) + +#define MRMAC_TICK_TRIGGER BIT(0) + +#define MRMAC_RESET_DELAY 1 /* Delay in msecs */ +#define MRMAC_BLKLCK_TIMEOUT 100 /* Block lock timeout in msecs */ +#define MRMAC_DMARST_TIMEOUT 500 /* MCDMA reset timeout in msecs */ + +#define XMCDMA_RX_OFFSET 0x500 +#define XMCDMA_CHAN_OFFSET 0x40 + +/* MCDMA Channel numbers are from 1-16 */ +#define XMCDMA_CHANNEL_1 BIT(0) +#define XMCDMA_CHANNEL_2 BIT(1) + +#define XMCDMA_CR_RUNSTOP BIT(0) +#define XMCDMA_CR_RESET BIT(2) + +#define XMCDMA_BD_CTRL_TXSOF_MASK BIT(31) /* First tx packet */ +#define XMCDMA_BD_CTRL_TXEOF_MASK BIT(30) /* Last tx packet */ +#define XMCDMA_BD_CTRL_ALL_MASK GENMASK(31, 30) /* All control bits */ +#define XMCDMA_BD_STS_ALL_MASK GENMASK(31, 28) /* All status bits */ + +/* MCDMA Mask registers */ +#define XMCDMA_CR_RUNSTOP_MASK BIT(0) /* Start/stop DMA channel */ +#define XMCDMA_CR_RESET_MASK BIT(2) /* Reset DMA engine */ + +#define XMCDMA_SR_HALTED_MASK BIT(0) +#define XMCDMA_SR_IDLE_MASK BIT(1) + +#define XMCDMA_CH_IDLE BIT(0) + +#define XMCDMA_BD_STS_COMPLETE BIT(31) /* Completed */ +#define XMCDMA_BD_STS_DEC_ERR BIT(20) /* Decode error */ +#define XMCDMA_BD_STS_SLV_ERR BIT(29) /* Slave error */ +#define XMCDMA_BD_STS_INT_ERR BIT(28) /* Internal err */ +#define XMCDMA_BD_STS_ALL_ERR GENMASK(30, 28) /* All errors */ + +#define XMCDMA_IRQ_ERRON_OTHERQ_MASK BIT(3) +#define XMCDMA_IRQ_PKTDROP_MASK BIT(4) +#define XMCDMA_IRQ_IOC_MASK BIT(5) +#define XMCDMA_IRQ_DELAY_MASK BIT(6) +#define XMCDMA_IRQ_ERR_MASK BIT(7) +#define XMCDMA_IRQ_ALL_MASK GENMASK(7, 5) +#define XMCDMA_PKTDROP_COALESCE_MASK GENMASK(15, 8) +#define XMCDMA_COALESCE_MASK GENMASK(23, 16) +#define XMCDMA_DELAY_MASK GENMASK(31, 24) + +#define MRMAC_CTL_DATA_RATE_MASK GENMASK(2, 0) +#define MRMAC_CTL_DATA_RATE_10G 0 +#define MRMAC_CTL_DATA_RATE_25G 1 +#define MRMAC_CTL_DATA_RATE_40G 2 +#define MRMAC_CTL_DATA_RATE_50G 3 +#define MRMAC_CTL_DATA_RATE_100G 4 + +#define MRMAC_CTL_AXIS_CFG_MASK GENMASK(11, 9) +#define MRMAC_CTL_AXIS_CFG_SHIFT 9 +#define MRMAC_CTL_AXIS_CFG_10G_IND 1 +#define MRMAC_CTL_AXIS_CFG_25G_IND 1 + +#define MRMAC_CTL_SERDES_WIDTH_MASK GENMASK(6, 4) +#define MRMAC_CTL_SERDES_WIDTH_SHIFT 4 +#define MRMAC_CTL_SERDES_WIDTH_10G 4 +#define MRMAC_CTL_SERDES_WIDTH_25G 6 + +#define MRMAC_CTL_RATE_CFG_MASK (MRMAC_CTL_DATA_RATE_MASK | \ + MRMAC_CTL_AXIS_CFG_MASK | \ + MRMAC_CTL_SERDES_WIDTH_MASK) + +#define MRMAC_CTL_PM_TICK_MASK BIT(30) +#define MRMAC_TICK_TRIGGER BIT(0) + +#define XMCDMA_BD_STS_ACTUAL_LEN_MASK 0x007fffff /* Actual length */ + +/* MCDMA common offsets */ +struct mcdma_common_regs { + u32 control; /* Common control */ + u32 status; /* Common status */ + u32 chen; /* Channel enable/disable */ + u32 chser; /* Channel in progress */ + u32 err; /* Error */ + u32 ch_schd_type; /* Channel Q scheduler type */ + u32 wrr_reg1; /* Weight of each channel (ch1-8) */ + u32 wrr_reg2; /* Weight of each channel (ch9-16) */ + u32 ch_serviced; /* Channels completed */ + u32 arcache_aruser; /* ARCACHE and ARUSER values for AXI4 read */ + u32 intr_status; /* Interrupt monitor */ + u32 reserved[5]; +}; + +/* MCDMA per-channel registers */ +struct mcdma_chan_reg { + u32 control; /* Control */ + u32 status; /* Status */ + u32 current; /* Current descriptor */ + u32 current_hi; /* Current descriptor high 32bit */ + u32 tail; /* Tail descriptor */ + u32 tail_hi; /* Tail descriptor high 32bit */ + u32 pktcnt; /* Packet processed count */ +}; + +/* MCDMA buffer descriptors */ +struct mcdma_bd { + u32 next_desc; /* Next descriptor pointer */ + u32 next_desc_msb; + u32 buf_addr; /* Buffer address */ + u32 buf_addr_msb; + u32 reserved1; + u32 cntrl; /* Control */ + u32 status; /* Status */ + u32 sband_stats; + u32 app0; + u32 app1; /* Tx start << 16 | insert */ + u32 app2; /* Tx csum seed */ + u32 app3; + u32 app4; + u32 sw_id_offset; + u32 reserved2; + u32 reserved3; + u32 reserved4[16]; +}; + +#endif /* __XILINX_AXI_MRMAC_H */ From bc579291e2292c80e6018826fa5eefa453756b17 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 2 Jul 2021 04:40:35 -0600 Subject: [PATCH 13/19] xilinx: versal: Enable Xilinx AXI MRMAC Enable Xilinx AXI MRMAC for Versal platforms. Signed-off-by: Ashok Reddy Soma Reviewed-by: Simon Glass Signed-off-by: Michal Simek --- configs/xilinx_versal_virt_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 121c3ae720..c8632f88c0 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -90,6 +90,7 @@ CONFIG_PHY_VITESSE=y CONFIG_PHY_FIXED=y CONFIG_PHY_GIGE=y CONFIG_XILINX_AXIEMAC=y +CONFIG_XILINX_AXIMRMAC=y CONFIG_ZYNQ_GEM=y CONFIG_ARM_DCC=y CONFIG_PL01X_SERIAL=y From bfc05d7e2af334c5907c38a94eddb18b5e92faaf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 13 Jul 2021 16:53:46 +0200 Subject: [PATCH 14/19] psci: Do not define do_poweroff() if CONFIG_SYSRESET_CMD_POWEROFF is enabled CONFIG_SYSRESET_CMD_POWEROFF defines do_poweroff() in sysreset-uclass.c that's why don't define it twice when both CONFIG_SYSRESET_CMD_POWEROFF and CONFIG_CMD_POWEROFF are enabled. CONFIG_SYSRESET_CMD_POWEROFF depends on CONFIG_CMD_POWEROFF. Signed-off-by: Michal Simek --- drivers/firmware/psci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 89cb7d88e5..657e7eb5ae 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -210,7 +210,7 @@ void psci_sys_poweroff(void) invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); } -#ifdef CONFIG_CMD_POWEROFF +#if IS_ENABLED(CONFIG_CMD_POWEROFF) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF) int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { do_psci_probe(); From f1bc214b0024b8d9585d83a42999a40980728303 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 13 Jul 2021 16:39:26 +0200 Subject: [PATCH 15/19] arm64: zynqmp: Do not define do_reset() if sysreset is enabled The SPL can also be compiled with sysreset drivers just fine, so update the condition to cater for that option. The same change was done by commit efa1a62ad2dd ("ARM: imx8m: Do not define do_reset() if sysreset is enabled"). Signed-off-by: Michal Simek --- board/xilinx/zynqmp/zynqmp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 18d5c515de..38c910fa5b 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -499,9 +499,11 @@ int dram_init(void) } #endif +#if !CONFIG_IS_ENABLED(SYSRESET) void reset_cpu(void) { } +#endif static u8 __maybe_unused zynqmp_get_bootmode(void) { From a9558b45a4ba3c4ceeb084532209eab553a2327e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 13 Jul 2021 16:49:04 +0200 Subject: [PATCH 16/19] arm64: zynqmp: Enable reset and poweroff via sysreset framework reset and poweroff are called via hooks in psci driver which is going around sysreset framework that's why enable sysreset drivers and do reset and poweroff via this framework. Using this flow will allow us to call SYSTEM_WARM_RESET based on psci 1.1 spec which can be calles with reset -w command. Signed-off-by: Michal Simek --- configs/xilinx_zynqmp_virt_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 5f32ca4930..bac1e181d2 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -157,6 +157,9 @@ CONFIG_ZYNQ_SERIAL=y CONFIG_SPI=y CONFIG_ZYNQ_SPI=y CONFIG_ZYNQMP_GQSPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_CMD_POWEROFF=y +CONFIG_SYSRESET_PSCI=y CONFIG_TPM2_TIS_SPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y From 9ca09621760453dc452244498fdbcd52e3e2f71d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 14 Jul 2021 09:07:04 +0200 Subject: [PATCH 17/19] arm64: versal: Drop default definitions of CONFIG_SYS_PBSIZE It is default value which had been converted by commit 432e39806805 ("include/configs: drop default definitions of CONFIG_SYS_PBSIZE"). That's why also remove it. Signed-off-by: Michal Simek --- include/configs/xilinx_versal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/configs/xilinx_versal.h b/include/configs/xilinx_versal.h index aae128f5ed..15a9db2a92 100644 --- a/include/configs/xilinx_versal.h +++ b/include/configs/xilinx_versal.h @@ -41,8 +41,6 @@ /* Monitor Command Prompt */ /* Console I/O Buffer Size */ #define CONFIG_SYS_CBSIZE 2048 -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ - sizeof(CONFIG_SYS_PROMPT) + 16) #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE #define CONFIG_SYS_MAXARGS 64 From 3965d13f933d5aa670f833eb9584f119e4a11d62 Mon Sep 17 00:00:00 2001 From: Raju Kumar Pothuraju Date: Mon, 12 Jul 2021 20:19:04 +0530 Subject: [PATCH 18/19] xilinx: Define kernel_comp_addr_r,kernel_comp_size env variables Add kernel_comp_addr_r, kernel_comp_size env variables for zynqmp and versal to be able to use the compressed kernel Image(.gz,.bz2,.lzma,.lzo) using booti command. Signed-off-by: Raju Kumar Pothuraju Signed-off-by: Michal Simek --- include/configs/xilinx_versal.h | 2 ++ include/configs/xilinx_zynqmp.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/configs/xilinx_versal.h b/include/configs/xilinx_versal.h index 15a9db2a92..62680ad238 100644 --- a/include/configs/xilinx_versal.h +++ b/include/configs/xilinx_versal.h @@ -65,6 +65,8 @@ "pxefile_addr_r=0x10000000\0" \ "kernel_addr_r=0x18000000\0" \ "kernel_size_r=0x10000000\0" \ + "kernel_comp_addr_r=0x30000000\0" \ + "kernel_comp_size=0x3C00000\0" \ "scriptaddr=0x20000000\0" \ "ramdisk_addr_r=0x02100000\0" \ "script_size_f=0x80000\0" diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index bfe8a20427..262154cdff 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -89,6 +89,8 @@ "pxefile_addr_r=0x10000000\0" \ "kernel_addr_r=0x18000000\0" \ "kernel_size_r=0x10000000\0" \ + "kernel_comp_addr_r=0x30000000\0" \ + "kernel_comp_size=0x3C00000\0" \ "scriptaddr=0x20000000\0" \ "ramdisk_addr_r=0x02100000\0" \ "script_size_f=0x80000\0" \ From 15ca9ebb074e9eca5a8264c93f5678df240fa54d Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Wed, 14 Jul 2021 06:17:19 -0600 Subject: [PATCH 19/19] arm64: zynqmp: Move USB3 PHY properties from DWC3 node to USB node Move the PHY properties from DWC3 node to USB node in ZynqMP DTs as here the USB3 PHY used is PSGTR, which is connected to Xilinx USB core. This PHY initialization should be handled from Xilinx USB core as the prerequisite register configurations are done here only. Signed-off-by: Manish Narani Signed-off-by: Michal Simek --- arch/arm/dts/zynqmp-p-a2197-00-revA.dts | 4 ++-- arch/arm/dts/zynqmp-sck-kv-g-revA.dts | 4 ++-- arch/arm/dts/zynqmp-sck-kv-g-revB.dts | 4 ++-- arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts | 4 ++-- arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts | 8 ++++---- arch/arm/dts/zynqmp-zcu100-revC.dts | 8 ++++---- arch/arm/dts/zynqmp-zcu102-revA.dts | 4 ++-- arch/arm/dts/zynqmp-zcu104-revA.dts | 4 ++-- arch/arm/dts/zynqmp-zcu104-revC.dts | 4 ++-- arch/arm/dts/zynqmp-zcu106-revA.dts | 4 ++-- arch/arm/dts/zynqmp-zcu111-revA.dts | 4 ++-- arch/arm/dts/zynqmp-zcu208-revA.dts | 4 ++-- arch/arm/dts/zynqmp-zcu216-revA.dts | 4 ++-- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/arch/arm/dts/zynqmp-p-a2197-00-revA.dts b/arch/arm/dts/zynqmp-p-a2197-00-revA.dts index d50b335e67..c893aaaafd 100644 --- a/arch/arm/dts/zynqmp-p-a2197-00-revA.dts +++ b/arch/arm/dts/zynqmp-p-a2197-00-revA.dts @@ -545,6 +545,8 @@ status = "okay"; xlnx,usb-polarity = <0>; xlnx,usb-reset-mode = <0>; + phy-names = "usb3-phy"; + phys = <&psgtr 1 PHY_TYPE_USB3 0 1>; }; &dwc3_0 { @@ -553,8 +555,6 @@ snps,dis_u2_susphy_quirk; snps,dis_u3_susphy_quirk; maximum-speed = "super-speed"; - phy-names = "usb3-phy"; - phys = <&psgtr 1 PHY_TYPE_USB3 0 1>; }; &usb1 { diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revA.dts b/arch/arm/dts/zynqmp-sck-kv-g-revA.dts index 59d5751e06..4e8086c82f 100644 --- a/arch/arm/dts/zynqmp-sck-kv-g-revA.dts +++ b/arch/arm/dts/zynqmp-sck-kv-g-revA.dts @@ -125,6 +125,8 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; usbhub: usb5744 { /* u43 */ compatible = "microchip,usb5744"; reset-gpios = <&gpio 44 GPIO_ACTIVE_HIGH>; @@ -135,8 +137,6 @@ status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revB.dts b/arch/arm/dts/zynqmp-sck-kv-g-revB.dts index b5443afff9..048d5665c5 100644 --- a/arch/arm/dts/zynqmp-sck-kv-g-revB.dts +++ b/arch/arm/dts/zynqmp-sck-kv-g-revB.dts @@ -109,14 +109,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts index b92a2ee3e6..4a87bd6a6a 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts @@ -424,14 +424,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts b/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts index 344323ab7f..13812470ae 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts @@ -221,27 +221,27 @@ &usb0 { status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 0 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 0 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; /* ULPI SMSC USB3320 */ &usb1 { status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; }; &dwc3_1 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts index 2d61577478..ea630a43dc 100644 --- a/arch/arm/dts/zynqmp-zcu100-revC.dts +++ b/arch/arm/dts/zynqmp-zcu100-revC.dts @@ -561,13 +561,13 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 0>; }; &dwc3_0 { status = "okay"; dr_mode = "peripheral"; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 0>; maximum-speed = "super-speed"; }; @@ -576,13 +576,13 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 0>; }; &dwc3_1 { status = "okay"; dr_mode = "host"; - phy-names = "usb3-phy"; - phys = <&psgtr 3 PHY_TYPE_USB3 1 0>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts index c1af5fc635..1b1cabb004 100644 --- a/arch/arm/dts/zynqmp-zcu102-revA.dts +++ b/arch/arm/dts/zynqmp-zcu102-revA.dts @@ -1019,14 +1019,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 7e5eca82fd..9cd30447eb 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -502,14 +502,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts index f4ebcbb318..45191569c1 100644 --- a/arch/arm/dts/zynqmp-zcu104-revC.dts +++ b/arch/arm/dts/zynqmp-zcu104-revC.dts @@ -514,14 +514,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts index ac6689c167..50cc72eb92 100644 --- a/arch/arm/dts/zynqmp-zcu106-revA.dts +++ b/arch/arm/dts/zynqmp-zcu106-revA.dts @@ -1012,14 +1012,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts index 8d57ca2b3b..2b15ce1ea8 100644 --- a/arch/arm/dts/zynqmp-zcu111-revA.dts +++ b/arch/arm/dts/zynqmp-zcu111-revA.dts @@ -849,14 +849,14 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu208-revA.dts b/arch/arm/dts/zynqmp-zcu208-revA.dts index d3e20ae85d..32a6e6fb55 100644 --- a/arch/arm/dts/zynqmp-zcu208-revA.dts +++ b/arch/arm/dts/zynqmp-zcu208-revA.dts @@ -692,13 +692,13 @@ /* ULPI SMSC USB3320 */ &usb0 { status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; }; diff --git a/arch/arm/dts/zynqmp-zcu216-revA.dts b/arch/arm/dts/zynqmp-zcu216-revA.dts index ae7c181968..1e347036d0 100644 --- a/arch/arm/dts/zynqmp-zcu216-revA.dts +++ b/arch/arm/dts/zynqmp-zcu216-revA.dts @@ -696,13 +696,13 @@ /* ULPI SMSC USB3320 */ &usb0 { status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; }; &dwc3_0 { status = "okay"; dr_mode = "host"; snps,usb3_lpm_capable; - phy-names = "usb3-phy"; - phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; maximum-speed = "super-speed"; };