From d622c240587477b1b56acfc11f9eaf120e0405dd Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Fri, 19 Jun 2020 22:45:47 -0600 Subject: [PATCH 01/50] zfs: fix missing include for disk_partition definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 0528979fa7ab ("part: Drop disk_partition_t typedef") changed to a struct. As a result it uncovered an apparent missing include in zfs_common.h for part.h which actually contains the definition. The ZFS handles the struct exclusively as pointers so it was only a warning. warning: ‘struct disk_partition’ declared inside parameter list will not be visible outside of this definition or declaration void zfs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info); Signed-off-by: Joel Johnson Series-CC: Simon Glass --- include/zfs_common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zfs_common.h b/include/zfs_common.h index 027ba91b28..cb83e59e83 100644 --- a/include/zfs_common.h +++ b/include/zfs_common.h @@ -22,6 +22,8 @@ #ifndef __ZFS_COMMON__ #define __ZFS_COMMON__ +#include + #define SECTOR_SIZE 0x200 #define SECTOR_BITS 9 From ccbda9e68093b0c6019b95596366faec2b19442d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 17 Jun 2020 15:07:04 -0300 Subject: [PATCH 02/50] phy: atheros: Fix the "qca,clk-out-frequency" example The correct name for the property is "qca,clk-out-frequency", so fix it accordingly. Signed-off-by: Fabio Estevam Reviewed-by: Michael Walle --- doc/device-tree-bindings/net/phy/atheros.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/device-tree-bindings/net/phy/atheros.txt b/doc/device-tree-bindings/net/phy/atheros.txt index 97e97b8c13..a72c6b050d 100644 --- a/doc/device-tree-bindings/net/phy/atheros.txt +++ b/doc/device-tree-bindings/net/phy/atheros.txt @@ -23,7 +23,7 @@ Example: ethernet-phy@0 { reg = <0>; - qca-clk-out-frequency = <125000000>; + qca,clk-out-frequency = <125000000>; qca,keep-pll-enabled; vddio-supply = <&vddio>; From 1a027a90aaa65ea429a55035f0316eadd0d83180 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 10 Jun 2020 21:18:23 +0200 Subject: [PATCH 03/50] nvme: Invalidate dcache before submitting admin cmd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch try to avoids eviction of dirty lines during DMA transfer. The code right now execute the following step: - allocate the buffer - start a dma operation using the non-coherent dma buffer - invalidate cache lines associated with the buffer - read the buffer This can lead to reading back not valid information, because the cache controller could evict dirty cache lines belonging to the buffer *after* the DMA operation has started to fill the DRAM. In order to avoid this, a new invalidation is required *before* starting the DMA operation. The patch just adds an invalidation before submitting the DMA command. Example below shows the nvme disk scan result without the following patch => nvme scan nvme_get_info_from_identify: nn = 544502629, vwc = 100, sn = dev_0T, mn = `�\�, fr = t_part, mdts = 105 So, invalidating the cache before submitting the admin command, fix the cpu read. Cc: André Przywara Reported-by: Suniel Mahesh Signed-off-by: Michael Trimarchi Signed-off-by: Jagan Teki Tested-by: Suniel Mahesh Reviewed-by: Bin Meng --- drivers/nvme/nvme.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 0357aba7f1..fc64d93ab8 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -466,6 +466,9 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid, c.identify.cns = cpu_to_le32(cns); + invalidate_dcache_range(dma_addr, + dma_addr + sizeof(struct nvme_id_ctrl)); + ret = nvme_submit_admin_cmd(dev, &c, NULL); if (!ret) invalidate_dcache_range(dma_addr, From d1896e365c385aee0d00f32d42ca5f905a8dac9e Mon Sep 17 00:00:00 2001 From: Vagrant Cascadian Date: Thu, 4 Jun 2020 10:42:01 -0700 Subject: [PATCH 04/50] cmd: booti: Fix spelling of "environment". Signed-off-by: Vagrant Cascadian Reviewed-by: Simon Glass --- cmd/booti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/booti.c b/cmd/booti.c index ae37975494..af0603b96e 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -141,7 +141,7 @@ static char booti_help_text[] = "\tspecifying the size of a RAW initrd.\n" "\tCurrently only booting from gz, bz2, lzma and lz4 compression\n" "\ttypes are supported. In order to boot from any of these compressed\n" - "\timages, user have to set kernel_comp_addr_r and kernel_comp_size enviornment\n" + "\timages, user have to set kernel_comp_addr_r and kernel_comp_size environment\n" "\tvariables beforehand.\n" #if defined(CONFIG_OF_LIBFDT) "\tSince booting a Linux kernel requires a flat device-tree, a\n" From 6d81eed9fd8071ed783289167ae979de6355b8c4 Mon Sep 17 00:00:00 2001 From: Vagrant Cascadian Date: Thu, 4 Jun 2020 10:42:02 -0700 Subject: [PATCH 05/50] doc: sifive: Fix spelling of "environment". Signed-off-by: Vagrant Cascadian --- doc/board/sifive/fu540.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst index f7c2c9f5bd..739eefa669 100644 --- a/doc/board/sifive/fu540.rst +++ b/doc/board/sifive/fu540.rst @@ -27,7 +27,7 @@ Building -------- 1. Add the RISC-V toolchain to your PATH. -2. Setup ARCH & cross compilation enviornment variable: +2. Setup ARCH & cross compilation environment variable: .. code-block:: none @@ -217,7 +217,7 @@ Or if you want to use a compressed kernel image file such as Image.gz =>setenv kernel_comp_addr_r 0x90000000 =>setenv kernel_comp_size 0x500000 -By this time, correct kernel image is loaded and required enviornment variables +By this time, correct kernel image is loaded and required environment variables are set. You can proceed to load the ramdisk and device tree from the tftp server as well. From 1c078ad7d954759d9021b126ad05d063a90ebae6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 May 2020 09:32:39 +0900 Subject: [PATCH 06/50] psci: add 'static inline' to invoke_psci_fn() stub Avoid potential multiple definitions when CONFIG_ARM_PSCI_FW is disabled. Signed-off-by: Masahiro Yamada --- include/linux/psci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/psci.h b/include/linux/psci.h index 9433df836b..841dbc8da7 100644 --- a/include/linux/psci.h +++ b/include/linux/psci.h @@ -91,8 +91,8 @@ unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); #else -unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, - unsigned long a2, unsigned long a3) +static inline unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3) { return PSCI_RET_DISABLED; } From d581076a33e7fd1f2b019a0a53eebe58d76623c1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 20 Jun 2020 14:28:25 +0200 Subject: [PATCH 07/50] cmd: mmc: Cache-align extcsd read target The extcsd read target must be cache aligned in case the controller uses DMA to read the extcsd register, make it so. Signed-off-by: Marek Vasut Reviewed-by: Michael Trimarchi --- cmd/mmc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/mmc.c b/cmd/mmc.c index 1c252e0502..1529a3e05d 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,8 @@ static void print_mmcinfo(struct mmc *mmc) if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) { bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0; bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR); - u8 wp, ext_csd[MMC_MAX_BLOCK_LEN]; + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); + u8 wp; int ret; #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING) From 135c10a7834aa7e0f26f52e5173925e695cba48f Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Mon, 22 Jun 2020 19:38:03 +0800 Subject: [PATCH 08/50] mmc: fsl_esdhc_imx: fix the mask for tuning start point According the RM, the bit[6~0] of register ESDHC_TUNING_CTRL is TUNING_START_TAP, bit[7] of this register is to disable the command CRC check for standard tuning. So fix it here. Fixes: fa33d207494c ("mmc: split fsl_esdhc driver for i.MX") Signed-off-by: Haibo Chen --- include/fsl_esdhc_imx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fsl_esdhc_imx.h b/include/fsl_esdhc_imx.h index 33c6d52bfe..220a76b9ee 100644 --- a/include/fsl_esdhc_imx.h +++ b/include/fsl_esdhc_imx.h @@ -203,7 +203,7 @@ #define ESDHC_STD_TUNING_EN BIT(24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP_DEFAULT 0x1 -#define ESDHC_TUNING_START_TAP_MASK 0xff +#define ESDHC_TUNING_START_TAP_MASK 0x7f #define ESDHC_TUNING_STEP_MASK 0x00070000 #define ESDHC_TUNING_STEP_SHIFT 16 From ba61676ff9f8225ebc0ea33ad9f48862e718fd01 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Mon, 22 Jun 2020 19:38:04 +0800 Subject: [PATCH 09/50] mmc: fsl_esdhc_imx: disable the CMD CRC check for standard tuning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In current code, we add 1ms dealy after each tuning command for standard tuning method. Adding this 1ms dealy is because USDHC default check the CMD CRC and DATA line. If detect the CMD CRC, USDHC standard tuning IC logic do not wait for the tuning data sending out by the card, trigger the buffer read ready interrupt immediately, and step to next cycle. So when next time the new tuning command send out by USDHC, card may still not send out the tuning data of the upper command,then some eMMC cards may stuck, can't response to any command, block the whole tuning procedure. If do not check the CMD CRC for tuning, then do not has this issue. USDHC will wait for the tuning data of each tuning command and check them. If the tuning data pass the check, it also means the CMD line also okay for tuning. So this patch disable the CMD CRC check for tuning, save some time for the whole tuning procedure. Signed-off-by: Haibo Chen --- drivers/mmc/fsl_esdhc_imx.c | 22 ++++++++++++---------- include/fsl_esdhc_imx.h | 1 + 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index f42e018434..5b61eeb214 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -907,19 +907,9 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) ctrl = readl(®s->autoc12err); if ((!(ctrl & MIX_CTRL_EXE_TUNE)) && (ctrl & MIX_CTRL_SMPCLK_SEL)) { - /* - * need to wait some time, make sure sd/mmc fininsh - * send out tuning data, otherwise, the sd/mmc can't - * response to any command when the card still out - * put the tuning data. - */ - mdelay(1); ret = 0; break; } - - /* Add 1ms delay for SD and eMMC */ - mdelay(1); } writel(irqstaten, ®s->irqstaten); @@ -1267,6 +1257,18 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, val |= priv->tuning_start_tap; val &= ~ESDHC_TUNING_STEP_MASK; val |= (priv->tuning_step) << ESDHC_TUNING_STEP_SHIFT; + + /* Disable the CMD CRC check for tuning, if not, need to + * add some delay after every tuning command, because + * hardware standard tuning logic will directly go to next + * step once it detect the CMD CRC error, will not wait for + * the card side to finally send out the tuning data, trigger + * the buffer read ready interrupt immediately. If usdhc send + * the next tuning command some eMMC card will stuck, can't + * response, block the tuning procedure or the first command + * after the whole tuning procedure always can't get any response. + */ + val |= ESDHC_TUNING_CMD_CRC_CHECK_DISABLE; writel(val, ®s->tuning_ctrl); } } diff --git a/include/fsl_esdhc_imx.h b/include/fsl_esdhc_imx.h index 220a76b9ee..279a66d9bf 100644 --- a/include/fsl_esdhc_imx.h +++ b/include/fsl_esdhc_imx.h @@ -204,6 +204,7 @@ /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP_DEFAULT 0x1 #define ESDHC_TUNING_START_TAP_MASK 0x7f +#define ESDHC_TUNING_CMD_CRC_CHECK_DISABLE BIT(7) #define ESDHC_TUNING_STEP_MASK 0x00070000 #define ESDHC_TUNING_STEP_SHIFT 16 From fe95905ffed57d617cad81a71ac419d53aaa1ebf Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Mon, 15 Jun 2020 17:18:12 +0800 Subject: [PATCH 10/50] mmc: retry CMD1 in mmc_send_op_cond() until the eMMC is ready According to eMMC specification v5.1 section 6.4.3, we should issue CMD1 repeatedly in the idle state until the eMMC is ready even if mmc_send_op_cond() send CMD1 with argument = 0. Otherwise some eMMC devices seems to enter the inactive mode after mmc_complete_op_cond() issued CMD0 when the eMMC device is busy. Signed-off-by: Haibo Chen Reviewed-by: Peng Fan --- drivers/mmc/mmc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 620bb93064..725a36799d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -669,12 +669,15 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg) static int mmc_send_op_cond(struct mmc *mmc) { int err, i; + int timeout = 1000; + uint start; /* Some cards seem to need this */ mmc_go_idle(mmc); + start = get_timer(0); /* Asking to the card its capabilities */ - for (i = 0; i < 2; i++) { + for (i = 0; ; i++) { err = mmc_send_op_cond_iter(mmc, i != 0); if (err) return err; @@ -682,6 +685,10 @@ static int mmc_send_op_cond(struct mmc *mmc) /* exit if not busy (flag seems to be inverted) */ if (mmc->ocr & OCR_BUSY) break; + + if (get_timer(start) > timeout) + return -ETIMEDOUT; + udelay(100); } mmc->op_cond_pending = 1; return 0; From f12341a9529540113f01989149bbbeb68662a829 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 18 Jun 2020 19:33:12 +0530 Subject: [PATCH 11/50] mmc: sdhci: Fix HISPD bit handling SDHCI HISPD bits need to be configured based on desired mmc timings mode and some HISPD quirks. So, handle the HISPD bit based on the mmc computed selected mode(timing parameter) rather than fixed mmc card clock frequency. Linux handle the HISPD similar like this in below commit but no SDHCI_QUIRK_BROKEN_HISPD_MODE, commit <501639bf2173> ("mmc: sdhci: fix SDHCI_QUIRK_NO_HISPD_BIT handling") This eventually fixed the mmc write issue observed in rk3399 sdhci controller. Bug log for refernece, => gpt write mmc 0 $partitions Writing GPT: mmc write failed ** Can't write to device 0 ** ** Can't write to device 0 ** error! Cc: Kever Yang Cc: Peng Fan Peng Fan: added back "ctrl &= ~SDHCI_CTRL_HISPD;" per Jaehoon's suggestion Tested-by: Suniel Mahesh # roc-rk3399-pc Signed-off-by: Jagan Teki --- drivers/mmc/sdhci.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 92cc8434af..f4eb655f6e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -567,6 +567,7 @@ static int sdhci_set_ios(struct mmc *mmc) #endif u32 ctrl; struct sdhci_host *host = mmc->priv; + bool no_hispd_bit = false; if (host->ops && host->ops->set_control_reg) host->ops->set_control_reg(host); @@ -594,14 +595,26 @@ static int sdhci_set_ios(struct mmc *mmc) ctrl &= ~SDHCI_CTRL_4BITBUS; } - if (mmc->clock > 26000000) - ctrl |= SDHCI_CTRL_HISPD; - else - ctrl &= ~SDHCI_CTRL_HISPD; - if ((host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) || - (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE)) + (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE)) { ctrl &= ~SDHCI_CTRL_HISPD; + no_hispd_bit = true; + } + + if (!no_hispd_bit) { + if (mmc->selected_mode == MMC_HS || + mmc->selected_mode == SD_HS || + mmc->selected_mode == MMC_DDR_52 || + mmc->selected_mode == MMC_HS_200 || + mmc->selected_mode == MMC_HS_400 || + mmc->selected_mode == UHS_SDR25 || + mmc->selected_mode == UHS_SDR50 || + mmc->selected_mode == UHS_SDR104 || + mmc->selected_mode == UHS_DDR50) + ctrl |= SDHCI_CTRL_HISPD; + else + ctrl &= ~SDHCI_CTRL_HISPD; + } sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); From b1c272d18b50fae1465a8049d5b2802fcc424106 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 22 Jun 2020 23:50:50 -0700 Subject: [PATCH 12/50] cmd: bootefi: Fix fdt_size variable type in efi_carve_out_dt_rsv() Variable fdt_size should be of type 'fdt_size_t', not 'fdt_addr_t'. Fixes 0d7c2913fdf7: ("cmd: bootefi: Honor the address & size cells properties correctly") Signed-off-by: Bin Meng Reviewed-by: Heinrich Schuchardt --- cmd/bootefi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index ac713cad1b..8269153973 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -189,7 +189,8 @@ static void efi_carve_out_dt_rsv(void *fdt) if (nodeoffset >= 0) { subnode = fdt_first_subnode(fdt, nodeoffset); while (subnode >= 0) { - fdt_addr_t fdt_addr, fdt_size; + fdt_addr_t fdt_addr; + fdt_size_t fdt_size; /* check if this subnode has a reg property */ fdt_addr = fdtdec_get_addr_size_auto_parent( From 915f15ac5746739da0aa2ee2840c2d00dc65aaaa Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 24 Jun 2020 12:14:49 +0200 Subject: [PATCH 13/50] efi_loader: type of efi_secure_mode Variable efi_secure_mode is meant to hold a value of enum efi_secure_mode. So it should not be defined as int but as enum efi_secure_mode. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index e097670e28..4d275b23ce 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -27,7 +27,7 @@ enum efi_secure_mode { }; static bool efi_secure_boot; -static int efi_secure_mode; +static enum efi_secure_mode efi_secure_mode; static u8 efi_vendor_keys; #define READ_ONLY BIT(31) From d80dd9e7853256f27847238771bf34c7157b8894 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 24 Jun 2020 12:38:00 +0200 Subject: [PATCH 14/50] efi_loader: size of secure boot variables The variables SetupMode, AuditMode, DeployedMode are explicitly defined as UINT8 in the UEFI specification. The type of SecureBoot is UINT8 in EDK2. Use variable name secure_boot instead of sec_boot for the value of the UEFI variable SecureBoot. Avoid abbreviations in function descriptions. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 4d275b23ce..6271dbcf41 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -185,17 +185,17 @@ static const char *parse_attr(const char *str, u32 *attrp, u64 *timep) /** * efi_set_secure_state - modify secure boot state variables - * @sec_boot: value of SecureBoot + * @secure_boot: value of SecureBoot * @setup_mode: value of SetupMode * @audit_mode: value of AuditMode * @deployed_mode: value of DeployedMode * - * Modify secure boot stat-related variables as indicated. + * Modify secure boot status related variables as indicated. * * Return: status code */ -static efi_status_t efi_set_secure_state(int sec_boot, int setup_mode, - int audit_mode, int deployed_mode) +static efi_status_t efi_set_secure_state(u8 secure_boot, u8 setup_mode, + u8 audit_mode, u8 deployed_mode) { u32 attributes; efi_status_t ret; @@ -204,8 +204,8 @@ static efi_status_t efi_set_secure_state(int sec_boot, int setup_mode, EFI_VARIABLE_RUNTIME_ACCESS | READ_ONLY; ret = efi_set_variable_common(L"SecureBoot", &efi_global_variable_guid, - attributes, sizeof(sec_boot), &sec_boot, - false); + attributes, sizeof(secure_boot), + &secure_boot, false); if (ret != EFI_SUCCESS) goto err; From 4b78b5bfdae8d655924d01aa332ea179c2885c62 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 25 Jun 2020 08:14:57 -0300 Subject: [PATCH 15/50] ARM: dts: imx6q-tbs2910: Fix Ethernet regression Since commit: commit 6333cbb3817ed551cd7d4e92f7359c73ccc567fc Author: Michael Walle Date: Thu May 7 00:11:58 2020 +0200 phy: atheros: ar8035: remove static clock config We can configure the clock output in the device tree. Disable the hardcoded one in here. This is highly board-specific and should have never been enabled in the PHY driver. If bisecting shows that this commit breaks your board it probably depends on the clock output of your Atheros AR8035 PHY. Please have a look at doc/device-tree-bindings/net/phy/atheros.txt. You need to set "clk-out-frequency = <125000000>" because that value was the hardcoded value until this commit. Signed-off-by: Michael Walle Acked-by: Joe Hershberger , the clock output setting for the AR803x driver is removed from being hardcoded in the PHY driver and should be passed via device tree instead. Update the device tree with the "qca,clk-out-frequency" property so that Ethernet can work again. Reported-by: Soeren Moch Signed-off-by: Fabio Estevam Tested-by: Soeren Moch --- arch/arm/dts/imx6q-tbs2910.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/dts/imx6q-tbs2910.dts b/arch/arm/dts/imx6q-tbs2910.dts index cc5df37b46..7d0a0676ff 100644 --- a/arch/arm/dts/imx6q-tbs2910.dts +++ b/arch/arm/dts/imx6q-tbs2910.dts @@ -107,7 +107,18 @@ pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii-id"; phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + phy-handle = <&phy>; status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy: ethernet-phy@4 { + reg = <4>; + qca,clk-out-frequency = <125000000>; + }; + }; }; &hdmi { From 8a204312abad7913f9b2209a71bef81853647b21 Mon Sep 17 00:00:00 2001 From: Ley Foon Tan Date: Thu, 25 Jun 2020 19:19:09 +0800 Subject: [PATCH 16/50] arm: socfpga: misc_s10: Fix EMAC register address calculation Fix EMAC register address calculation, address need to multiply with sizeof(u32) or 4. This fixes write to invalid address. Signed-off-by: Ley Foon Tan --- arch/arm/mach-socfpga/misc_s10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-socfpga/misc_s10.c b/arch/arm/mach-socfpga/misc_s10.c index ccff78a230..670bfa1a31 100644 --- a/arch/arm/mach-socfpga/misc_s10.c +++ b/arch/arm/mach-socfpga/misc_s10.c @@ -68,7 +68,7 @@ static u32 socfpga_phymode_setup(u32 gmac_index, const char *phymode) return -EINVAL; clrsetbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0 + - gmac_index, + (gmac_index * sizeof(u32)), SYSMGR_EMACGRP_CTRL_PHYSEL_MASK, modereg); return 0; From 6a28dc3322982ac67b01c66d9aa34531978deb16 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Mon, 8 Jun 2020 10:17:08 -0400 Subject: [PATCH 17/50] rk3399: Add BOOTENV_SF command Add missing BOOTENV_SF command in rk3399 config. Fix it. Fixes: f263b860acf8 ("rk3399: Enable SF distro bootcmd") Signed-off-by: Jagan Teki Reported-by: Suniel Mahesh Tested-by: Suniel Mahesh Reviewed-by: Kever Yang --- include/configs/rk3399_common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h index f0ae6e67a7..e63ebb14f7 100644 --- a/include/configs/rk3399_common.h +++ b/include/configs/rk3399_common.h @@ -67,6 +67,7 @@ "partitions=" PARTS_DEFAULT \ ROCKCHIP_DEVICE_SETTINGS \ BOOTENV \ + BOOTENV_SF \ "altbootcmd=" \ "setenv boot_syslinux_conf extlinux/extlinux-rollback.conf;" \ "run distro_bootcmd\0" From a2b1cff8b86964ea630d23aa687c23bba40c9f4b Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Mon, 22 Jun 2020 16:19:25 +0300 Subject: [PATCH 18/50] rockchip: rk3188: Fix back to BROM boot Move the setting for noc remap out of SPL code. Changing noc remap inside SPL results in breaking back to BROM boot. Fixes commit c14fe2a8e192 ("rockchip: rk3188: Move SoC one time setting into arch_cpu_init()"). Signed-off-by: Alexander Kochetkov Reviewed-by: Kever Yang --- arch/arm/mach-rockchip/rk3188/rk3188.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-rockchip/rk3188/rk3188.c b/arch/arm/mach-rockchip/rk3188/rk3188.c index ef57dfd761..1b2f4a4757 100644 --- a/arch/arm/mach-rockchip/rk3188/rk3188.c +++ b/arch/arm/mach-rockchip/rk3188/rk3188.c @@ -77,15 +77,32 @@ int arch_cpu_init(void) BYPASSSEL_MASK | BYPASSDMEN_MASK, 1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT); #endif + return 0; +} +#endif + +__weak int rk3188_board_late_init(void) +{ + return 0; +} + +int rk_board_late_init(void) +{ + struct rk3188_grf *grf; + + grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (IS_ERR(grf)) { + pr_err("grf syscon returned %ld\n", PTR_ERR(grf)); + return 0; + } /* enable noc remap to mimic legacy loaders */ rk_clrsetreg(&grf->soc_con0, NOC_REMAP_MASK << NOC_REMAP_SHIFT, NOC_REMAP_MASK << NOC_REMAP_SHIFT); - return 0; + return rk3188_board_late_init(); } -#endif #ifdef CONFIG_SPL_BUILD static int setup_led(void) From 5e15dcb4cbc7906690a759554be082b025d2aa52 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Mon, 22 Jun 2020 16:17:09 +0300 Subject: [PATCH 19/50] rockchip: clk: rk3188: change APLL to safe 600MHz The commit 84a6a27ae3ff ("rockchip: rk3188: init CPU freq in clock driver") changed ARM clock from 600MHz to 1600MHz. It made boot unstable due to the fact that PMIC at the start generates insufficient voltage for operation. See also: commit f4f57c58b589 ("rockchip: rk3188: Setup the armclk in spl"). Fixes commit 84a6a27ae3ff ("rockchip: rk3188: init CPU freq in clock driver"). Signed-off-by: Alexander Kochetkov Reviewed-by: Kever Yang --- drivers/clk/rockchip/clk_rk3188.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c index 11e3bd33cb..aacc8cf2d1 100644 --- a/drivers/clk/rockchip/clk_rk3188.c +++ b/drivers/clk/rockchip/clk_rk3188.c @@ -569,7 +569,8 @@ static int rk3188_clk_probe(struct udevice *dev) rkclk_init(priv->cru, priv->grf, priv->has_bwadj); /* Init CPU frequency */ - rkclk_configure_cpu(priv->cru, priv->grf, APLL_HZ, priv->has_bwadj); + rkclk_configure_cpu(priv->cru, priv->grf, APLL_SAFE_HZ, + priv->has_bwadj); #endif return 0; From bab68b2d889e7d3783c4f31b67025b086b7278c3 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 10 Jun 2020 02:52:23 -0700 Subject: [PATCH 20/50] video: bmp: support 8bits BMP drawing on 24/32 bpp framebuffer Update video bmp code so that we can display 8 bits logo on 24 or 32 bpp framebuffer. Signed-off-by: Ye Li Signed-off-by: Anatolij Gustschin Reviewed-by: Jagan Teki Tested-by: Jagan Teki # bpi-m1+, bpi-m64 --- drivers/video/video_bmp.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index eb9636541d..7d7f37b445 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -233,6 +233,8 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, */ if (bpix != bmp_bpix && !(bmp_bpix == 8 && bpix == 16) && + !(bmp_bpix == 8 && bpix == 24) && + !(bmp_bpix == 8 && bpix == 32) && !(bmp_bpix == 24 && bpix == 16) && !(bmp_bpix == 24 && bpix == 32)) { printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", @@ -265,6 +267,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, switch (bmp_bpix) { case 1: case 8: { + struct bmp_color_table_entry *cte; cmap_base = priv->cmap; #ifdef CONFIG_VIDEO_BMP_RLE8 u32 compression = get_unaligned_le32(&bmp->header.compression); @@ -280,21 +283,33 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, break; } #endif - - if (bpix != 16) + byte_width = width * (bpix / 8); + if (!byte_width) byte_width = width; - else - byte_width = width * 2; for (i = 0; i < height; ++i) { WATCHDOG_RESET(); for (j = 0; j < width; j++) { - if (bpix != 16) { + if (bpix == 8) { fb_put_byte(&fb, &bmap); - } else { + } else if (bpix == 16) { *(uint16_t *)fb = cmap_base[*bmap]; bmap++; fb += sizeof(uint16_t) / sizeof(*fb); + } else { + /* Only support big endian */ + cte = &palette[*bmap]; + bmap++; + if (bpix == 24) { + *(fb++) = cte->red; + *(fb++) = cte->green; + *(fb++) = cte->blue; + } else { + *(fb++) = cte->blue; + *(fb++) = cte->green; + *(fb++) = cte->red; + *(fb++) = 0; + } } } bmap += (padded_width - width); From 8cee2006caec73e6a7b1d32e63d55efc724b07c7 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 10 Jun 2020 02:52:21 -0700 Subject: [PATCH 21/50] video: vidconsole: avoid multiple lines overwrite logo Fix the bug that multiple lines wraps to overwrite logo bmp display. Signed-off-by: Ye Li Reviewed-by: Jagan Teki Tested-by: Jagan Teki # bpi-m1+, bpi-m64 --- drivers/video/vidconsole-uclass.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index d30e6db6f6..9b76154721 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -622,6 +622,7 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row) col *= priv->x_charsize; row *= priv->y_charsize; priv->xcur_frac = VID_TO_POS(min_t(short, col, vid_priv->xsize - 1)); + priv->xstart_frac = priv->xcur_frac; priv->ycur = min_t(short, row, vid_priv->ysize - 1); } From 70b06d95426c016ce302b408f6d2ba9bd3bbda02 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 10 Jun 2020 02:52:22 -0700 Subject: [PATCH 22/50] splash: Fix build warning on 64 bits CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Get below warning on ARM64 platform, because the bmp_load_addr is defined to u32. common/splash.c: In function ‘splash_video_logo_load’: common/splash.c:74:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 74 | memcpy((void *)bmp_load_addr, bmp_logo_bitmap, Signed-off-by: Ye Li Reviewed-by: Jagan Teki Tested-by: Jagan Teki # bpi-m1+, bpi-m64 --- common/splash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/splash.c b/common/splash.c index e7d847726d..2b9313e03f 100644 --- a/common/splash.c +++ b/common/splash.c @@ -59,7 +59,7 @@ static struct splash_location default_splash_locations[] = { static int splash_video_logo_load(void) { char *splashimage; - u32 bmp_load_addr; + ulong bmp_load_addr; splashimage = env_get("splashimage"); if (!splashimage) From 670eda329329d591d276b02c8918e7918aaedde7 Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Wed, 24 Jun 2020 10:43:59 +0200 Subject: [PATCH 23/50] video: check hardware version of DSI Check the hardware version of DSI. Versions 1.30 & 1.31 are only supported. Signed-off-by: Yannick Fertre Reviewed-by: Patrick Delaunay Reviewed-by: Philippe Cornu --- drivers/video/stm32/stm32_dsi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c index 04796435f1..31ab8ebec7 100644 --- a/drivers/video/stm32/stm32_dsi.c +++ b/drivers/video/stm32/stm32_dsi.c @@ -271,7 +271,6 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, u32 val; /* Update lane capabilities according to hw version */ - dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; dsi->lane_min_kbps = LANE_MIN_KBPS; dsi->lane_max_kbps = LANE_MAX_KBPS; if (dsi->hw_version == HWVER_131) { @@ -475,6 +474,15 @@ static int stm32_dsi_probe(struct udevice *dev) /* Reset */ reset_deassert(&rst); + /* check hardware version */ + priv->hw_version = dsi_read(priv, DSI_VERSION) & VERSION; + if (priv->hw_version != HWVER_130 && + priv->hw_version != HWVER_131) { + dev_err(dev, "DSI version 0x%x not supported\n", priv->hw_version); + ret = -ENODEV; + goto err_clk; + } + return 0; err_clk: clk_disable(&clk); From 36e66e3cd6067c2b38f97047193fc447a1842834 Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Wed, 24 Jun 2020 10:45:39 +0200 Subject: [PATCH 24/50] video: mipi update panel platform data Add new fields "lanes, format & mode_flags" to structure mipi_dsi_panel_plat. Signed-off-by: Yannick Fertre Reviewed-by: Patrick Delaunay --- include/mipi_dsi.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/mipi_dsi.h b/include/mipi_dsi.h index 83c5163cf8..c8a7d3daef 100644 --- a/include/mipi_dsi.h +++ b/include/mipi_dsi.h @@ -221,9 +221,15 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) /** * struct mipi_dsi_panel_plat - DSI panel platform data * @device: DSI peripheral device + * @lanes: number of active data lanes + * @format: pixel format for video mode + * @mode_flags: DSI operation mode related flags */ struct mipi_dsi_panel_plat { struct mipi_dsi_device *device; + unsigned int lanes; + enum mipi_dsi_pixel_format format; + unsigned long mode_flags; }; /** From 7084dd8c4bf212cf4b25dc1cf34d35f9b5999f9d Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Wed, 24 Jun 2020 10:45:40 +0200 Subject: [PATCH 25/50] video: stm32: stm32_dsi: copy DSI fields Copy the DSI data link characteristics from panel platform data to mipi DSI device. Signed-off-by: Yannick Fertre Reviewed-by: Patrick Delaunay --- drivers/video/stm32/stm32_dsi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c index 31ab8ebec7..283151398b 100644 --- a/drivers/video/stm32/stm32_dsi.c +++ b/drivers/video/stm32/stm32_dsi.c @@ -353,6 +353,9 @@ static int stm32_dsi_attach(struct udevice *dev) mplat = dev_get_platdata(priv->panel); mplat->device = &priv->device; + device->lanes = mplat->lanes; + device->format = mplat->format; + device->mode_flags = mplat->mode_flags; ret = panel_get_display_timing(priv->panel, &timings); if (ret) { From ac824e80eab1a7730b9b413bc777c8c1404491b5 Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Wed, 24 Jun 2020 10:45:41 +0200 Subject: [PATCH 26/50] video: raydium_rm68200: fill characteristics of DSI data link Fill characteristics of DSI data link to platform data instead of mipi device to avoid memory corruption. Signed-off-by: Yannick Fertre Reviewed-by: Patrick Delaunay --- drivers/video/raydium-rm68200.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/video/raydium-rm68200.c b/drivers/video/raydium-rm68200.c index 9169280fb8..353894503b 100644 --- a/drivers/video/raydium-rm68200.c +++ b/drivers/video/raydium-rm68200.c @@ -75,9 +75,6 @@ struct rm68200_panel_priv { struct udevice *reg; struct udevice *backlight; struct gpio_desc reset; - unsigned int lanes; - enum mipi_dsi_pixel_format format; - unsigned long mode_flags; }; static const struct display_timing default_timing = { @@ -259,17 +256,8 @@ static int rm68200_panel_enable_backlight(struct udevice *dev) static int rm68200_panel_get_display_timing(struct udevice *dev, struct display_timing *timings) { - struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); - struct mipi_dsi_device *device = plat->device; - struct rm68200_panel_priv *priv = dev_get_priv(dev); - memcpy(timings, &default_timing, sizeof(*timings)); - /* fill characteristics of DSI data link */ - device->lanes = priv->lanes; - device->format = priv->format; - device->mode_flags = priv->mode_flags; - return 0; } @@ -308,6 +296,7 @@ static int rm68200_panel_ofdata_to_platdata(struct udevice *dev) static int rm68200_panel_probe(struct udevice *dev) { struct rm68200_panel_priv *priv = dev_get_priv(dev); + struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); int ret; if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { @@ -322,9 +311,10 @@ static int rm68200_panel_probe(struct udevice *dev) dm_gpio_set_value(&priv->reset, false); mdelay(10); - priv->lanes = 2; - priv->format = MIPI_DSI_FMT_RGB888; - priv->mode_flags = MIPI_DSI_MODE_VIDEO | + /* fill characteristics of DSI data link */ + plat->lanes = 2; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM; From bccb385a83a5f9ee603a30de1d39b03fd6f45b23 Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Wed, 24 Jun 2020 10:45:42 +0200 Subject: [PATCH 27/50] video: orisetech_otm8009a: fill characteristics of DSI data link Fill characteristics of DSI data link to platform data instead of mipi device to avoid memory corruption. Signed-off-by: Yannick Fertre Reviewed-by: Patrick Delaunay --- drivers/video/orisetech_otm8009a.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/video/orisetech_otm8009a.c b/drivers/video/orisetech_otm8009a.c index b1f2dd403e..362bf6a6fe 100644 --- a/drivers/video/orisetech_otm8009a.c +++ b/drivers/video/orisetech_otm8009a.c @@ -62,9 +62,6 @@ struct otm8009a_panel_priv { struct udevice *reg; struct gpio_desc reset; - unsigned int lanes; - enum mipi_dsi_pixel_format format; - unsigned long mode_flags; }; static const struct display_timing default_timing = { @@ -293,17 +290,8 @@ static int otm8009a_panel_enable_backlight(struct udevice *dev) static int otm8009a_panel_get_display_timing(struct udevice *dev, struct display_timing *timings) { - struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); - struct mipi_dsi_device *device = plat->device; - struct otm8009a_panel_priv *priv = dev_get_priv(dev); - memcpy(timings, &default_timing, sizeof(*timings)); - /* fill characteristics of DSI data link */ - device->lanes = priv->lanes; - device->format = priv->format; - device->mode_flags = priv->mode_flags; - return 0; } @@ -335,6 +323,7 @@ static int otm8009a_panel_ofdata_to_platdata(struct udevice *dev) static int otm8009a_panel_probe(struct udevice *dev) { struct otm8009a_panel_priv *priv = dev_get_priv(dev); + struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); int ret; if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { @@ -350,9 +339,10 @@ static int otm8009a_panel_probe(struct udevice *dev) dm_gpio_set_value(&priv->reset, false); mdelay(10); /* >5ms */ - priv->lanes = 2; - priv->format = MIPI_DSI_FMT_RGB888; - priv->mode_flags = MIPI_DSI_MODE_VIDEO | + /* fill characteristics of DSI data link */ + plat->lanes = 2; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM; From 673eb44e91bc0c06cb1e3f353f5d07b4f9e5a586 Mon Sep 17 00:00:00 2001 From: Patrick Wildt Date: Sun, 7 Jun 2020 20:36:12 +0200 Subject: [PATCH 28/50] rockchip: correctly set vop0 or vop1 The EDP_LCDC_SEL bit has to be set correctly to select vop0 or vop1, but so far we have set it in both conditions, which is not correct. Can someone verify this is the correct way round? vop1 -> set, vop0 -> clear? Signed-off-by: Patrick Wildt Reviewed-by: Kever Yang --- drivers/video/rockchip/rk_edp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c index 92188be927..000bd48140 100644 --- a/drivers/video/rockchip/rk_edp.c +++ b/drivers/video/rockchip/rk_edp.c @@ -1062,7 +1062,8 @@ static int rk_edp_probe(struct udevice *dev) rk_setreg(&priv->grf->soc_con12, 1 << 4); /* select epd signal from vop0 or vop1 */ - rk_setreg(&priv->grf->soc_con6, (vop_id == 1) ? (1 << 5) : (1 << 5)); + rk_clrsetreg(&priv->grf->soc_con6, (1 << 5), + (vop_id == 1) ? (1 << 5) : (0 << 5)); rockchip_edp_wait_hpd(priv); From 35ee34b2c2adc961e1ae4e68c5b7e380d7c448a0 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 29 Jun 2020 16:53:44 +0200 Subject: [PATCH 29/50] video: rockchip: fix HDMI 4K resolution 3480 is not valid XRES, use 3840 as default. Fixes: 05c65a82c3c1 ("video: rockchip: Support 4K resolution for rk3399, HDMI") Signed-off-by: Anatolij Gustschin Cc: Jagan Teki Reviewed-by: Jagan Teki Tested-by: Jagan Teki # roc-rk3399-pc --- drivers/video/rockchip/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index cfd774ead6..5215a71f99 100644 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -22,7 +22,7 @@ menuconfig VIDEO_ROCKCHIP config VIDEO_ROCKCHIP_MAX_XRES int "Maximum horizontal resolution (for memory allocation purposes)" depends on VIDEO_ROCKCHIP - default 3480 if ROCKCHIP_RK3399 && DISPLAY_ROCKCHIP_HDMI + default 3840 if ROCKCHIP_RK3399 && DISPLAY_ROCKCHIP_HDMI default 1920 help The maximum horizontal resolution to support for the framebuffer. From b9c52c50905cfd5973418e925e72c3bbefc7eb34 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:11 +0200 Subject: [PATCH 30/50] net: pcnet: Drop typedef struct pcnet_priv_t Use struct pcnet_priv all over the place instead. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 260a5a38cf..c6f080d956 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -76,15 +76,15 @@ struct pcnet_uncached_priv { struct pcnet_init_block init_block; }; -typedef struct pcnet_priv { +struct pcnet_priv { struct pcnet_uncached_priv *uc; /* Receive Buffer space */ unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; int cur_rx; int cur_tx; -} pcnet_priv_t; +}; -static pcnet_priv_t *lp; +static struct pcnet_priv *lp; /* Offsets from base I/O address for WIO mode */ #define PCNET_RDP 0x10 @@ -340,9 +340,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (unsigned long)malloc(sizeof(pcnet_priv_t) + 0x10); + addr = (unsigned long)malloc(sizeof(*lp) + 0x10); addr = (addr + 0xf) & ~0xf; - lp = (pcnet_priv_t *)addr; + lp = (struct pcnet_priv *)addr; addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); From b92b8f48fb47c48b3f9df91ea1009b5789d55e19 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:12 +0200 Subject: [PATCH 31/50] net: pcnet: Drop PCNET_HAS_PROM All of one PCNET users has this option set, make this default and drop this config option. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 5 ----- include/configs/malta.h | 1 - 2 files changed, 6 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index c6f080d956..edc4dba24c 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -241,10 +241,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; char *chipname; - -#ifdef PCNET_HAS_PROM int i; -#endif /* Reset the PCnet controller */ pcnet_reset(dev); @@ -279,7 +276,6 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) PCNET_DEBUG1("AMD %s\n", chipname); -#ifdef PCNET_HAS_PROM /* * In most chips, after a chip reset, the ethernet address is read from * the station address PROM at the base address and programmed into the @@ -293,7 +289,6 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; } -#endif /* PCNET_HAS_PROM */ return 0; } diff --git a/include/configs/malta.h b/include/configs/malta.h index 773d7c23ed..82c90042d9 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -16,7 +16,6 @@ #define CONFIG_PCI_GT64120 #define CONFIG_PCI_MSC01 #define CONFIG_PCNET -#define PCNET_HAS_PROM #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 From d3b1df0f396adb2b5c25ff655c3dae8624c41e50 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:13 +0200 Subject: [PATCH 32/50] net: pcnet: Use PCI_DEVICE() to define PCI device compat list Use this macro to fully fill the PCI device ID table. This is mandatory for the DM PCI support, which checks all the fields. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index edc4dba24c..e7ce79e952 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -155,7 +155,7 @@ static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, } static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE}, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE) }, {} }; From 89369b0ac2ca0621bfc30baed739bb9d9e7fdcad Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:14 +0200 Subject: [PATCH 33/50] net: pcnet: Simplify private data allocation The current code is horribly complex. Both the RX and TX buffer descriptors are 16 bytes in size, the init block is 32 bytes in size, so simplify the code such that the entire private data of the driver are allocated cache aligned and the RX and TX buffer descriptors are part of the private data. This removes multiple malloc calls and cache flushes. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index e7ce79e952..72b9380624 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -74,12 +75,13 @@ struct pcnet_uncached_priv { struct pcnet_rx_head rx_ring[RX_RING_SIZE]; struct pcnet_tx_head tx_ring[TX_RING_SIZE]; struct pcnet_init_block init_block; -}; +} __aligned(ARCH_DMA_MINALIGN); struct pcnet_priv { - struct pcnet_uncached_priv *uc; + struct pcnet_uncached_priv ucp; /* Receive Buffer space */ - unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; + unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; + struct pcnet_uncached_priv *uc; int cur_rx; int cur_tx; }; @@ -335,22 +337,11 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (unsigned long)malloc(sizeof(*lp) + 0x10); - addr = (addr + 0xf) & ~0xf; - lp = (struct pcnet_priv *)addr; - - addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, - sizeof(*lp->uc)); - flush_dcache_range(addr, addr + sizeof(*lp->uc)); - addr = (unsigned long)map_physmem(addr, - roundup(sizeof(*lp->uc), ARCH_DMA_MINALIGN), - MAP_NOCACHE); - lp->uc = (struct pcnet_uncached_priv *)addr; - - addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, - sizeof(*lp->rx_buf)); - flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); - lp->rx_buf = (void *)addr; + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); } uc = lp->uc; @@ -364,7 +355,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i]); + addr = pcnet_virt_to_mem(dev, lp->rx_buf[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -521,7 +512,7 @@ static int pcnet_recv (struct eth_device *dev) printf("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); } else { - buf = (*lp->rx_buf)[lp->cur_rx]; + buf = lp->rx_buf[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, (unsigned long)buf + pkt_len); net_process_received_packet(buf, pkt_len); From 0e11d79a533e3c874be1c5975abbc52aaba94d93 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:15 +0200 Subject: [PATCH 34/50] net: pcnet: Replace memset+malloc with calloc This combination of functions can be replaced with calloc(), make it so. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 72b9380624..b670cff2aa 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -184,12 +184,11 @@ int pcnet_initialize(bd_t *bis) /* * Allocate and pre-fill the device structure. */ - dev = (struct eth_device *)malloc(sizeof(*dev)); + dev = calloc(1, sizeof(*dev)); if (!dev) { printf("pcnet: Can not allocate memory\n"); break; } - memset(dev, 0, sizeof(*dev)); dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); From ada6a2cea5a0d44c3bd64713babd9d73eaf64863 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:16 +0200 Subject: [PATCH 35/50] net: pcnet: Move private data allocation to initialize The private data allocation does not have to be done every time the NIC is initialized at run time, move the allocation to initialize function, which means it will be done only once when the driver starts. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b670cff2aa..073ffca6b6 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -189,6 +189,20 @@ int pcnet_initialize(bd_t *bis) printf("pcnet: Can not allocate memory\n"); break; } + + /* + * We only maintain one structure because the drivers will + * never be used concurrently. In 32bit mode the RX and TX + * ring entries must be aligned on 16-byte boundaries. + */ + if (!lp) { + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + } + dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); @@ -330,19 +344,6 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) val |= 0x3 << 10; pcnet_write_csr(dev, 80, val); - /* - * We only maintain one structure because the drivers will never - * be used concurrently. In 32bit mode the RX and TX ring entries - * must be aligned on 16-byte boundaries. - */ - if (lp == NULL) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - uc = lp->uc; uc->init_block.mode = cpu_to_le16(0x0000); From 54c6067486e576eea70020d743a0a19d5ad1e603 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:17 +0200 Subject: [PATCH 36/50] net: pcnet: Move initialize function at the end Move the function at the end of the driver, so we could drop various forward declarations later. No functional change. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 180 ++++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 91 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 073ffca6b6..6d464cd0a4 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -161,97 +161,6 @@ static struct pci_device_id supported[] = { {} }; - -int pcnet_initialize(bd_t *bis) -{ - pci_dev_t devbusfn; - struct eth_device *dev; - u16 command, status; - int dev_nr = 0; - u32 bar; - - PCNET_DEBUG1("\npcnet_initialize...\n"); - - for (dev_nr = 0;; dev_nr++) { - - /* - * Find the PCnet PCI device(s). - */ - devbusfn = pci_find_devices(supported, dev_nr); - if (devbusfn < 0) - break; - - /* - * Allocate and pre-fill the device structure. - */ - dev = calloc(1, sizeof(*dev)); - if (!dev) { - printf("pcnet: Can not allocate memory\n"); - break; - } - - /* - * We only maintain one structure because the drivers will - * never be used concurrently. In 32bit mode the RX and TX - * ring entries must be aligned on 16-byte boundaries. - */ - if (!lp) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - - dev->priv = (void *)(unsigned long)devbusfn; - sprintf(dev->name, "pcnet#%d", dev_nr); - - /* - * Setup the PCI device. - */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); - dev->iobase = pci_mem_to_phys(devbusfn, bar); - dev->iobase &= ~0xf; - - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", - dev->name, devbusfn, (unsigned long)dev->iobase); - - command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(devbusfn, PCI_COMMAND, command); - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - if ((status & command) != command) { - printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); - free(dev); - continue; - } - - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); - - /* - * Probe the PCnet chip. - */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { - free(dev); - continue; - } - - /* - * Setup device structure and register the driver. - */ - dev->init = pcnet_init; - dev->halt = pcnet_halt; - dev->send = pcnet_send; - dev->recv = pcnet_recv; - - eth_register(dev); - } - - udelay(10 * 1000); - - return dev_nr; -} - static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; @@ -548,3 +457,92 @@ static void pcnet_halt(struct eth_device *dev) if (i <= 0) printf("%s: TIMEOUT: controller reset failed\n", dev->name); } + +int pcnet_initialize(bd_t *bis) +{ + pci_dev_t devbusfn; + struct eth_device *dev; + u16 command, status; + int dev_nr = 0; + u32 bar; + + PCNET_DEBUG1("\npcnet_initialize...\n"); + + for (dev_nr = 0; ; dev_nr++) { + /* + * Find the PCnet PCI device(s). + */ + devbusfn = pci_find_devices(supported, dev_nr); + if (devbusfn < 0) + break; + + /* + * Allocate and pre-fill the device structure. + */ + dev = calloc(1, sizeof(*dev)); + if (!dev) { + printf("pcnet: Can not allocate memory\n"); + break; + } + + /* + * We only maintain one structure because the drivers will + * never be used concurrently. In 32bit mode the RX and TX + * ring entries must be aligned on 16-byte boundaries. + */ + if (!lp) { + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + } + + dev->priv = (void *)(unsigned long)devbusfn; + sprintf(dev->name, "pcnet#%d", dev_nr); + + /* + * Setup the PCI device. + */ + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); + dev->iobase = pci_mem_to_phys(devbusfn, bar); + dev->iobase &= ~0xf; + + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", + dev->name, devbusfn, (unsigned long)dev->iobase); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config_word(devbusfn, PCI_COMMAND, command); + pci_read_config_word(devbusfn, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("%s: Couldn't enable IO access or Bus Mastering\n", + dev->name); + free(dev); + continue; + } + + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); + + /* + * Probe the PCnet chip. + */ + if (pcnet_probe(dev, bis, dev_nr) < 0) { + free(dev); + continue; + } + + /* + * Setup device structure and register the driver. + */ + dev->init = pcnet_init; + dev->halt = pcnet_halt; + dev->send = pcnet_send; + dev->recv = pcnet_recv; + + eth_register(dev); + } + + udelay(10 * 1000); + + return dev_nr; +} From 553286a63ca5e60beb4cf5af68795c7d78a19ceb Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:18 +0200 Subject: [PATCH 37/50] net: pcnet: Drop useless forward declarations Remove those as they are not needed anymore. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 6d464cd0a4..d8249f0a1c 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -141,12 +141,6 @@ static int pcnet_check(struct eth_device *dev) return readw(base + PCNET_RAP) == 88; } -static int pcnet_init (struct eth_device *dev, bd_t * bis); -static int pcnet_send(struct eth_device *dev, void *packet, int length); -static int pcnet_recv (struct eth_device *dev); -static void pcnet_halt (struct eth_device *dev); -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); - static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, void *addr) { From ab6ecbdc3c25761756538129c26d1396dd5b02a9 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:19 +0200 Subject: [PATCH 38/50] net: pcnet: Wrap devbusfn into private data Instead of using eth_device priv for this PCI devbusfn, free it so it could be used for driver private data, and wrap devbusfn into those driver private data. Note that using the name dev for the variable is a trick left for later, when DM support is in place, so dm_pci_virt_to_mem() can be used with minimal ifdeffery. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index d8249f0a1c..f7f1b8fc21 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -82,6 +82,7 @@ struct pcnet_priv { /* Receive Buffer space */ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; + pci_dev_t dev; int cur_rx; int cur_tx; }; @@ -141,13 +142,11 @@ static int pcnet_check(struct eth_device *dev) return readw(base + PCNET_RAP) == 88; } -static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, - void *addr) +static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) { - pci_dev_t devbusfn = (pci_dev_t)(unsigned long)dev->priv; void *virt_addr = addr; - return pci_virt_to_mem(devbusfn, virt_addr); + return pci_virt_to_mem(lp->dev, virt_addr); } static struct pci_device_id supported[] = { @@ -258,7 +257,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, lp->rx_buf[i]); + addr = pcnet_virt_to_mem(lp, lp->rx_buf[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -290,9 +289,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - addr = pcnet_virt_to_mem(dev, uc->rx_ring); + addr = pcnet_virt_to_mem(lp, uc->rx_ring); uc->init_block.rx_ring = cpu_to_le32(addr); - addr = pcnet_virt_to_mem(dev, uc->tx_ring); + addr = pcnet_virt_to_mem(lp, uc->tx_ring); uc->init_block.tx_ring = cpu_to_le32(addr); PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", @@ -303,7 +302,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * Tell the controller where the Init Block is located. */ barrier(); - addr = pcnet_virt_to_mem(dev, &lp->uc->init_block); + addr = pcnet_virt_to_mem(lp, &lp->uc->init_block); pcnet_write_csr(dev, 1, addr & 0xffff); pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); @@ -361,7 +360,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) * Setup Tx ring. Caution: the write order is important here, * set the status with the "ownership" bits last. */ - addr = pcnet_virt_to_mem(dev, packet); + addr = pcnet_virt_to_mem(lp, packet); writew(-pkt_len, &entry->length); writel(0, &entry->misc); writel(addr, &entry->base); @@ -492,7 +491,7 @@ int pcnet_initialize(bd_t *bis) (unsigned long)lp + sizeof(*lp)); } - dev->priv = (void *)(unsigned long)devbusfn; + lp->dev = devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); /* From 834d5cebe582eb71a2c76fc5c9078a3a85b1cafe Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:20 +0200 Subject: [PATCH 39/50] net: pcnet: Pass private data through dev->priv Get rid of the global point to private data, and rather pass it thought dev->priv. Also remove the unnecessary check for lp being non-NULL, since it is always NULL at this point. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index f7f1b8fc21..dab08c07ad 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -87,8 +87,6 @@ struct pcnet_priv { int cur_tx; }; -static struct pcnet_priv *lp; - /* Offsets from base I/O address for WIO mode */ #define PCNET_RDP 0x10 #define PCNET_RAP 0x12 @@ -212,6 +210,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) static int pcnet_init(struct eth_device *dev, bd_t *bis) { + struct pcnet_priv *lp = dev->priv; struct pcnet_uncached_priv *uc; int i, val; unsigned long addr; @@ -331,6 +330,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) { + struct pcnet_priv *lp = dev->priv; int i, status; u32 addr; struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; @@ -379,6 +379,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) static int pcnet_recv (struct eth_device *dev) { + struct pcnet_priv *lp = dev->priv; struct pcnet_rx_head *entry; unsigned char *buf; int pkt_len = 0; @@ -455,6 +456,7 @@ int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; struct eth_device *dev; + struct pcnet_priv *lp; u16 command, status; int dev_nr = 0; u32 bar; @@ -483,15 +485,13 @@ int pcnet_initialize(bd_t *bis) * never be used concurrently. In 32bit mode the RX and TX * ring entries must be aligned on 16-byte boundaries. */ - if (!lp) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); lp->dev = devbusfn; + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + dev->priv = lp; sprintf(dev->name, "pcnet#%d", dev_nr); /* From deca77382114364ca476482ad3e8bd431578fea8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:21 +0200 Subject: [PATCH 40/50] net: pcnet: Wrap iobase into private data Instead of using the non-DM-only iobase in struct eth_device, add one into the private data to make DM and non-DM operation possible. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 103 ++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index dab08c07ad..b0bd4af203 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -83,6 +83,7 @@ struct pcnet_priv { unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; pci_dev_t dev; + void __iomem *iobase; int cur_rx; int cur_tx; }; @@ -93,51 +94,39 @@ struct pcnet_priv { #define PCNET_RESET 0x14 #define PCNET_BDP 0x16 -static u16 pcnet_read_csr(struct eth_device *dev, int index) +static u16 pcnet_read_csr(struct pcnet_priv *lp, int index) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - return readw(base + PCNET_RDP); + writew(index, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_RDP); } -static void pcnet_write_csr(struct eth_device *dev, int index, u16 val) +static void pcnet_write_csr(struct pcnet_priv *lp, int index, u16 val) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - writew(val, base + PCNET_RDP); + writew(index, lp->iobase + PCNET_RAP); + writew(val, lp->iobase + PCNET_RDP); } -static u16 pcnet_read_bcr(struct eth_device *dev, int index) +static u16 pcnet_read_bcr(struct pcnet_priv *lp, int index) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - return readw(base + PCNET_BDP); + writew(index, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_BDP); } -static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val) +static void pcnet_write_bcr(struct pcnet_priv *lp, int index, u16 val) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - writew(val, base + PCNET_BDP); + writew(index, lp->iobase + PCNET_RAP); + writew(val, lp->iobase + PCNET_BDP); } -static void pcnet_reset(struct eth_device *dev) +static void pcnet_reset(struct pcnet_priv *lp) { - void __iomem *base = (void __iomem *)dev->iobase; - - readw(base + PCNET_RESET); + readw(lp->iobase + PCNET_RESET); } -static int pcnet_check(struct eth_device *dev) +static int pcnet_check(struct pcnet_priv *lp) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(88, base + PCNET_RAP); - return readw(base + PCNET_RAP) == 88; + writew(88, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_RAP) == 88; } static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) @@ -154,22 +143,22 @@ static struct pci_device_id supported[] = { static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { + struct pcnet_priv *lp = dev->priv; int chip_version; char *chipname; int i; /* Reset the PCnet controller */ - pcnet_reset(dev); + pcnet_reset(lp); /* Check if register access is working */ - if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { + if (pcnet_read_csr(lp, 0) != 4 || !pcnet_check(lp)) { printf("%s: CSR register access check failed\n", dev->name); return -1; } /* Identify the chip */ - chip_version = - pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16); + chip_version = pcnet_read_csr(lp, 88) | (pcnet_read_csr(lp, 89) << 16); if ((chip_version & 0xfff) != 0x003) return -1; chip_version = (chip_version >> 12) & 0xffff; @@ -199,7 +188,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) for (i = 0; i < 3; i++) { unsigned int val; - val = pcnet_read_csr(dev, i + 12) & 0x0ffff; + val = pcnet_read_csr(lp, i + 12) & 0x0ffff; /* There may be endianness issues here. */ dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; @@ -218,17 +207,17 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); /* Switch pcnet to 32bit mode */ - pcnet_write_bcr(dev, 20, 2); + pcnet_write_bcr(lp, 20, 2); /* Set/reset autoselect bit */ - val = pcnet_read_bcr(dev, 2) & ~2; + val = pcnet_read_bcr(lp, 2) & ~2; val |= 2; - pcnet_write_bcr(dev, 2, val); + pcnet_write_bcr(lp, 2, val); /* Enable auto negotiate, setup, disable fd */ - val = pcnet_read_bcr(dev, 32) & ~0x98; + val = pcnet_read_bcr(lp, 32) & ~0x98; val |= 0x20; - pcnet_write_bcr(dev, 32, val); + pcnet_write_bcr(lp, 32, val); /* * Enable NOUFLO on supported controllers, with the transmit @@ -238,12 +227,12 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * slower devices. Controllers which do not support NOUFLO will * simply be left with a larger transmit FIFO threshold. */ - val = pcnet_read_bcr(dev, 18); + val = pcnet_read_bcr(lp, 18); val |= 1 << 11; - pcnet_write_bcr(dev, 18, val); - val = pcnet_read_csr(dev, 80); + pcnet_write_bcr(lp, 18, val); + val = pcnet_read_csr(lp, 80); val |= 0x3 << 10; - pcnet_write_csr(dev, 80, val); + pcnet_write_csr(lp, 80, val); uc = lp->uc; @@ -302,28 +291,28 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ barrier(); addr = pcnet_virt_to_mem(lp, &lp->uc->init_block); - pcnet_write_csr(dev, 1, addr & 0xffff); - pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); + pcnet_write_csr(lp, 1, addr & 0xffff); + pcnet_write_csr(lp, 2, (addr >> 16) & 0xffff); - pcnet_write_csr(dev, 4, 0x0915); - pcnet_write_csr(dev, 0, 0x0001); /* start */ + pcnet_write_csr(lp, 4, 0x0915); + pcnet_write_csr(lp, 0, 0x0001); /* start */ /* Wait for Init Done bit */ for (i = 10000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x0100) + if (pcnet_read_csr(lp, 0) & 0x0100) break; udelay(10); } if (i <= 0) { printf("%s: TIMEOUT: controller init failed\n", dev->name); - pcnet_reset(dev); + pcnet_reset(lp); return -1; } /* * Finally start network controller operation. */ - pcnet_write_csr(dev, 0, 0x0002); + pcnet_write_csr(lp, 0, 0x0002); return 0; } @@ -367,7 +356,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) writew(0x8300, &entry->status); /* Trigger an immediate send poll. */ - pcnet_write_csr(dev, 0, 0x0008); + pcnet_write_csr(lp, 0, 0x0008); failure: if (++lp->cur_tx >= TX_RING_SIZE) @@ -435,16 +424,17 @@ static int pcnet_recv (struct eth_device *dev) static void pcnet_halt(struct eth_device *dev) { + struct pcnet_priv *lp = dev->priv; int i; PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); /* Reset the PCnet controller */ - pcnet_reset(dev); + pcnet_reset(lp); /* Wait for Stop bit */ for (i = 1000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x4) + if (pcnet_read_csr(lp, 0) & 0x4) break; udelay(10); } @@ -498,11 +488,10 @@ int pcnet_initialize(bd_t *bis) * Setup the PCI device. */ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); - dev->iobase = pci_mem_to_phys(devbusfn, bar); - dev->iobase &= ~0xf; + lp->iobase = (void *)(pci_mem_to_phys(devbusfn, bar) & ~0xf); - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", - dev->name, devbusfn, (unsigned long)dev->iobase); + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%p: ", + dev->name, devbusfn, lp->iobase); command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); From 6d76c9f1e6df5338aeaa8699e16ea3bb755f858d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:22 +0200 Subject: [PATCH 41/50] net: pcnet: Wrap name and enetaddr into private data Instead of using the non-DM-only name and enetaddr in struct eth_device, add pointers into the private data which can either point to that non-DM name or a DM one later on. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b0bd4af203..669b256178 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -84,6 +84,8 @@ struct pcnet_priv { struct pcnet_uncached_priv *uc; pci_dev_t dev; void __iomem *iobase; + char *name; + u8 *enetaddr; int cur_rx; int cur_tx; }; @@ -153,7 +155,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) /* Check if register access is working */ if (pcnet_read_csr(lp, 0) != 4 || !pcnet_check(lp)) { - printf("%s: CSR register access check failed\n", dev->name); + printf("%s: CSR register access check failed\n", lp->name); return -1; } @@ -174,7 +176,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) break; default: printf("%s: PCnet version %#x not supported\n", - dev->name, chip_version); + lp->name, chip_version); return -1; } @@ -190,8 +192,8 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) val = pcnet_read_csr(lp, i + 12) & 0x0ffff; /* There may be endianness issues here. */ - dev->enetaddr[2 * i] = val & 0x0ff; - dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; + lp->enetaddr[2 * i] = val & 0x0ff; + lp->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; } return 0; @@ -204,7 +206,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) int i, val; unsigned long addr; - PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); + PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); /* Switch pcnet to 32bit mode */ pcnet_write_bcr(lp, 20, 2); @@ -271,7 +273,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->uc->init_block); for (i = 0; i < 6; i++) { - lp->uc->init_block.phys_addr[i] = dev->enetaddr[i]; + lp->uc->init_block.phys_addr[i] = lp->enetaddr[i]; PCNET_DEBUG1(" %02x", lp->uc->init_block.phys_addr[i]); } @@ -304,7 +306,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) udelay(10); } if (i <= 0) { - printf("%s: TIMEOUT: controller init failed\n", dev->name); + printf("%s: TIMEOUT: controller init failed\n", lp->name); pcnet_reset(lp); return -1; } @@ -340,7 +342,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) } if (i <= 0) { printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", - dev->name, lp->cur_tx, status); + lp->name, lp->cur_tx, status); pkt_len = 0; goto failure; } @@ -385,7 +387,7 @@ static int pcnet_recv (struct eth_device *dev) err_status = status >> 8; if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", dev->name, lp->cur_rx); + printf("%s: Rx%d", lp->name, lp->cur_rx); PCNET_DEBUG1(" (status=0x%x)", err_status); if (err_status & 0x20) printf(" Frame"); @@ -402,7 +404,7 @@ static int pcnet_recv (struct eth_device *dev) pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; if (pkt_len < 60) { printf("%s: Rx%d: invalid packet length %d\n", - dev->name, lp->cur_rx, pkt_len); + lp->name, lp->cur_rx, pkt_len); } else { buf = lp->rx_buf[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, @@ -427,7 +429,7 @@ static void pcnet_halt(struct eth_device *dev) struct pcnet_priv *lp = dev->priv; int i; - PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); + PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); /* Reset the PCnet controller */ pcnet_reset(lp); @@ -439,7 +441,7 @@ static void pcnet_halt(struct eth_device *dev) udelay(10); } if (i <= 0) - printf("%s: TIMEOUT: controller reset failed\n", dev->name); + printf("%s: TIMEOUT: controller reset failed\n", lp->name); } int pcnet_initialize(bd_t *bis) @@ -451,7 +453,7 @@ int pcnet_initialize(bd_t *bis) int dev_nr = 0; u32 bar; - PCNET_DEBUG1("\npcnet_initialize...\n"); + PCNET_DEBUG1("\n%s...\n", __func__); for (dev_nr = 0; ; dev_nr++) { /* @@ -483,6 +485,8 @@ int pcnet_initialize(bd_t *bis) (unsigned long)lp + sizeof(*lp)); dev->priv = lp; sprintf(dev->name, "pcnet#%d", dev_nr); + lp->name = dev->name; + lp->enetaddr = dev->enetaddr; /* * Setup the PCI device. @@ -491,14 +495,14 @@ int pcnet_initialize(bd_t *bis) lp->iobase = (void *)(pci_mem_to_phys(devbusfn, bar) & ~0xf); PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%p: ", - dev->name, devbusfn, lp->iobase); + lp->name, devbusfn, lp->iobase); command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); pci_read_config_word(devbusfn, PCI_COMMAND, &status); if ((status & command) != command) { printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); + lp->name); free(dev); continue; } From f5e7df58e0b96f97e1d8ef49415401a51e9f18b8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:23 +0200 Subject: [PATCH 42/50] net: pcnet: Split common and non-DM functions Pull the common parts of functions out so they can be reused by both DM and non-DM code paths. The recv() function had to be reworked to fit into this scheme and this means it now only receives one packet at a time instead of spinning in an endless loop. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 149 ++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 55 deletions(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 669b256178..0a4cab8208 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -86,6 +86,7 @@ struct pcnet_priv { void __iomem *iobase; char *name; u8 *enetaddr; + u16 status; int cur_rx; int cur_tx; }; @@ -143,9 +144,8 @@ static struct pci_device_id supported[] = { {} }; -static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) +static int pcnet_probe_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; int chip_version; char *chipname; int i; @@ -199,9 +199,8 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) return 0; } -static int pcnet_init(struct eth_device *dev, bd_t *bis) +static int pcnet_init_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; struct pcnet_uncached_priv *uc; int i, val; unsigned long addr; @@ -319,9 +318,8 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) return 0; } -static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) +static int pcnet_send_common(struct pcnet_priv *lp, void *packet, int pkt_len) { - struct pcnet_priv *lp = dev->priv; int i, status; u32 addr; struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; @@ -368,65 +366,70 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) return pkt_len; } -static int pcnet_recv (struct eth_device *dev) +static int pcnet_recv_common(struct pcnet_priv *lp, unsigned char **bufp) { - struct pcnet_priv *lp = dev->priv; struct pcnet_rx_head *entry; unsigned char *buf; int pkt_len = 0; - u16 status, err_status; + u16 err_status; - while (1) { - entry = &lp->uc->rx_ring[lp->cur_rx]; - /* - * If we own the next entry, it's a new packet. Send it up. - */ - status = readw(&entry->status); - if ((status & 0x8000) != 0) - break; - err_status = status >> 8; + entry = &lp->uc->rx_ring[lp->cur_rx]; + /* + * If we own the next entry, it's a new packet. Send it up. + */ + lp->status = readw(&entry->status); + if ((lp->status & 0x8000) != 0) + return 0; + err_status = lp->status >> 8; - if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", lp->name, lp->cur_rx); - PCNET_DEBUG1(" (status=0x%x)", err_status); - if (err_status & 0x20) - printf(" Frame"); - if (err_status & 0x10) - printf(" Overflow"); - if (err_status & 0x08) - printf(" CRC"); - if (err_status & 0x04) - printf(" Fifo"); - printf(" Error\n"); - status &= 0x03ff; - - } else { - pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; - if (pkt_len < 60) { - printf("%s: Rx%d: invalid packet length %d\n", - lp->name, lp->cur_rx, pkt_len); - } else { - buf = lp->rx_buf[lp->cur_rx]; - invalidate_dcache_range((unsigned long)buf, - (unsigned long)buf + pkt_len); - net_process_received_packet(buf, pkt_len); - PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", - lp->cur_rx, pkt_len, buf); - } - } - - status |= 0x8000; - writew(status, &entry->status); - - if (++lp->cur_rx >= RX_RING_SIZE) - lp->cur_rx = 0; + if (err_status != 0x03) { /* There was an error. */ + printf("%s: Rx%d", lp->name, lp->cur_rx); + PCNET_DEBUG1(" (status=0x%x)", err_status); + if (err_status & 0x20) + printf(" Frame"); + if (err_status & 0x10) + printf(" Overflow"); + if (err_status & 0x08) + printf(" CRC"); + if (err_status & 0x04) + printf(" Fifo"); + printf(" Error\n"); + lp->status &= 0x03ff; + return 0; } + + pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; + if (pkt_len < 60) { + printf("%s: Rx%d: invalid packet length %d\n", + lp->name, lp->cur_rx, pkt_len); + return 0; + } + + *bufp = lp->rx_buf[lp->cur_rx]; + invalidate_dcache_range((unsigned long)*bufp, + (unsigned long)*bufp + pkt_len); + + PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", + lp->cur_rx, pkt_len, buf); + return pkt_len; } -static void pcnet_halt(struct eth_device *dev) +static void pcnet_free_pkt_common(struct pcnet_priv *lp, unsigned int len) +{ + struct pcnet_rx_head *entry; + + entry = &lp->uc->rx_ring[lp->cur_rx]; + + lp->status |= 0x8000; + writew(lp->status, &entry->status); + + if (++lp->cur_rx >= RX_RING_SIZE) + lp->cur_rx = 0; +} + +static void pcnet_halt_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; int i; PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); @@ -444,6 +447,42 @@ static void pcnet_halt(struct eth_device *dev) printf("%s: TIMEOUT: controller reset failed\n", lp->name); } +static int pcnet_init(struct eth_device *dev, bd_t *bis) +{ + struct pcnet_priv *lp = dev->priv; + + return pcnet_init_common(lp); +} + +static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) +{ + struct pcnet_priv *lp = dev->priv; + + return pcnet_send_common(lp, packet, pkt_len); +} + +static int pcnet_recv(struct eth_device *dev) +{ + struct pcnet_priv *lp = dev->priv; + uchar *packet; + int ret; + + ret = pcnet_recv_common(lp, &packet); + if (ret > 0) + net_process_received_packet(packet, ret); + if (ret) + pcnet_free_pkt_common(lp, ret); + + return ret; +} + +static void pcnet_halt(struct eth_device *dev) +{ + struct pcnet_priv *lp = dev->priv; + + pcnet_halt_common(lp); +} + int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; @@ -512,7 +551,7 @@ int pcnet_initialize(bd_t *bis) /* * Probe the PCnet chip. */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { + if (pcnet_probe_common(lp) < 0) { free(dev); continue; } From 53019cf35b5ccf9cb5ad8269acab494b99a3dc0c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:24 +0200 Subject: [PATCH 43/50] net: pcnet: Add DM support With all the changes in place, add support for DM into the pcnet driver. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 127 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 0a4cab8208..8e3e3dbbce 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -82,9 +83,14 @@ struct pcnet_priv { /* Receive Buffer space */ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; +#ifdef CONFIG_DM_ETH + struct udevice *dev; + const char *name; +#else pci_dev_t dev; - void __iomem *iobase; char *name; +#endif + void __iomem *iobase; u8 *enetaddr; u16 status; int cur_rx; @@ -136,7 +142,11 @@ static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) { void *virt_addr = addr; +#ifdef CONFIG_DM_ETH + return dm_pci_virt_to_mem(lp->dev, virt_addr); +#else return pci_virt_to_mem(lp->dev, virt_addr); +#endif } static struct pci_device_id supported[] = { @@ -447,6 +457,7 @@ static void pcnet_halt_common(struct pcnet_priv *lp) printf("%s: TIMEOUT: controller reset failed\n", lp->name); } +#ifndef CONFIG_DM_ETH static int pcnet_init(struct eth_device *dev, bd_t *bis) { struct pcnet_priv *lp = dev->priv; @@ -571,3 +582,117 @@ int pcnet_initialize(bd_t *bis) return dev_nr; } +#else /* DM_ETH */ +static int pcnet_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct pcnet_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + return pcnet_init_common(priv); +} + +static void pcnet_stop(struct udevice *dev) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + pcnet_halt_common(priv); +} + +static int pcnet_send(struct udevice *dev, void *packet, int length) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + int ret; + + ret = pcnet_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int pcnet_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + return pcnet_recv_common(priv, packetp); +} + +static int pcnet_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + pcnet_free_pkt_common(priv, length); + + return 0; +} + +static int pcnet_bind(struct udevice *dev) +{ + static int card_number; + char name[16]; + + sprintf(name, "pcnet#%u", card_number++); + + return device_set_name(dev, name); +} + +static int pcnet_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct pcnet_priv *lp = dev_get_priv(dev); + u16 command, status; + u32 iobase; + int ret; + + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase); + iobase &= ~0xf; + + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + lp->dev = dev; + lp->name = dev->name; + lp->enetaddr = plat->enetaddr; + lp->iobase = (void *)dm_pci_mem_to_phys(dev, iobase); + + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, command); + dm_pci_read_config16(dev, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("%s: Couldn't enable IO access or Bus Mastering\n", + lp->name); + return -EINVAL; + } + + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x20); + + ret = pcnet_probe_common(lp); + if (ret) + return ret; + + return 0; +} + +static const struct eth_ops pcnet_ops = { + .start = pcnet_start, + .send = pcnet_send, + .recv = pcnet_recv, + .stop = pcnet_stop, + .free_pkt = pcnet_free_pkt, +}; + +U_BOOT_DRIVER(eth_pcnet) = { + .name = "eth_pcnet", + .id = UCLASS_ETH, + .bind = pcnet_bind, + .probe = pcnet_probe, + .ops = &pcnet_ops, + .priv_auto_alloc_size = sizeof(struct pcnet_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_UC_FLAG_ALLOC_PRIV_DMA, +}; + +U_BOOT_PCI_DEVICE(eth_pcnet, supported); +#endif From d8553d6ee3146bc06b8f86787138293d3f6453c3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:25 +0200 Subject: [PATCH 44/50] net: pcnet: Add Kconfig entries Add Kconfig entries for the pcnet driver and convert MIPS malta to use those. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- configs/malta64_defconfig | 1 + configs/malta64el_defconfig | 1 + configs/malta_defconfig | 1 + configs/maltael_defconfig | 1 + drivers/net/Kconfig | 6 ++++++ include/configs/malta.h | 1 - 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig index e5a19a6e54..a16abc7fa9 100644 --- a/configs/malta64_defconfig +++ b/configs/malta64_defconfig @@ -27,6 +27,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig index e9de5bea6e..a9efe7736e 100644 --- a/configs/malta64el_defconfig +++ b/configs/malta64el_defconfig @@ -28,6 +28,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/malta_defconfig b/configs/malta_defconfig index 2b43818c81..0680f595db 100644 --- a/configs/malta_defconfig +++ b/configs/malta_defconfig @@ -26,6 +26,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig index ec984b5a35..31c9ff6a77 100644 --- a/configs/maltael_defconfig +++ b/configs/maltael_defconfig @@ -27,6 +27,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index bb23f73fc2..19703d42cd 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -392,6 +392,12 @@ config MII help Enable support of the Media-Independent Interface (MII) +config PCNET + bool "AMD PCnet series Ethernet controller driver" + help + This driver supports AMD PCnet series fast ethernet family of + PCI chipsets/adapters. + config RTL8139 bool "Realtek 8139 series Ethernet controller driver" help diff --git a/include/configs/malta.h b/include/configs/malta.h index 82c90042d9..9602773ff9 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -15,7 +15,6 @@ #define CONFIG_PCI_GT64120 #define CONFIG_PCI_MSC01 -#define CONFIG_PCNET #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 From 753a8922f8a34af43a14de1cdb4eec5ef82961ee Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 6 Jun 2020 22:21:47 +0200 Subject: [PATCH 45/50] tools: add script for byte endianness swapping This can be used to swap the byte endianness of a binary file from Little-Endian to Big-Endian or vice-versa. Signed-off-by: Daniel Schwierzeck --- tools/endian-swap.py | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 tools/endian-swap.py diff --git a/tools/endian-swap.py b/tools/endian-swap.py new file mode 100755 index 0000000000..5990efa313 --- /dev/null +++ b/tools/endian-swap.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ + +""" +Simple tool to swap the byte endianness of a binary file. +""" + +import argparse +import io + +def parse_args(): + """Parse command line arguments.""" + description = "Swap endianness of given input binary and write to output binary." + + parser = argparse.ArgumentParser(description=description) + parser.add_argument("input_bin", type=str, help="input binary") + parser.add_argument("output_bin", type=str, help="output binary") + parser.add_argument("-c", action="store", dest="chunk_size", type=int, + default=io.DEFAULT_BUFFER_SIZE, help="chunk size for reading") + + return parser.parse_args() + +def swap_chunk(chunk_orig): + """Swap byte endianness of the given chunk. + + Returns: + swapped chunk + """ + chunk = bytearray(chunk_orig) + + # align to 4 bytes and pad with 0x0 + chunk_len = len(chunk) + pad_len = chunk_len % 4 + if pad_len > 0: + chunk += b'\x00' * (4 - pad_len) + + chunk[0::4], chunk[1::4], chunk[2::4], chunk[3::4] =\ + chunk[3::4], chunk[2::4], chunk[1::4], chunk[0::4] + + return chunk + +def main(): + args = parse_args() + + with open(args.input_bin, "rb") as input_bin: + with open(args.output_bin, "wb") as output_bin: + while True: + chunk = bytearray(input_bin.read(args.chunk_size)) + if not chunk: + break + + output_bin.write(swap_chunk(chunk)) + +if __name__ == '__main__': + main() From b8cecd0c15e6cd65fae62070a69c590360ab73ab Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 6 Jun 2020 22:21:47 +0200 Subject: [PATCH 46/50] Makefile: add rule to generate u-boot-swap.bin This rule generates an u-boot binary file where the byte endianness is swapped. This will be used by the MIPS Malta Little-Endian variants to be able to boot with Qemu. The Qemu Malta Machine expects the firmware in Big-Endian order. Signed-off-by: Daniel Schwierzeck --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index e3c18d8c39..2a55a036b0 100644 --- a/Makefile +++ b/Makefile @@ -1733,6 +1733,12 @@ u-boot-mtk.bin: u-boot.bin FORCE $(call if_changed,mkimage) endif +quiet_cmd_endian_swap = SWAP $@ + cmd_endian_swap = $(srctree)/tools/endian-swap.py $< $@ + +u-boot-swap.bin: u-boot.bin FORCE + $(call if_changed,endian_swap) + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) # Rule to link u-boot From 5467434cc170b6649a2d85ef4a60ca58298689e8 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 6 Jun 2020 22:21:47 +0200 Subject: [PATCH 47/50] mips: malta: build u-boot-swap.bin The Qemu Malta machine expects the firmware in Big-Endian byte order. Therefore the Little-Endian variants of the Malta board needs to be byte swapped. Signed-off-by: Daniel Schwierzeck --- configs/malta64el_defconfig | 1 + configs/maltael_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig index a9efe7736e..a35ae86c55 100644 --- a/configs/malta64el_defconfig +++ b/configs/malta64el_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_TEXT_BASE=0xFFFFFFFFBE000000 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 CONFIG_TARGET_MALTA=y +CONFIG_BUILD_TARGET="u-boot-swap.bin" CONFIG_SYS_LITTLE_ENDIAN=y CONFIG_CPU_MIPS64_R2=y CONFIG_MISC_INIT_R=y diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig index 31c9ff6a77..b3f046c993 100644 --- a/configs/maltael_defconfig +++ b/configs/maltael_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_TEXT_BASE=0xBE000000 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 CONFIG_TARGET_MALTA=y +CONFIG_BUILD_TARGET="u-boot-swap.bin" CONFIG_SYS_LITTLE_ENDIAN=y CONFIG_MISC_INIT_R=y CONFIG_BOARD_EARLY_INIT_F=y From d8533167f5612e97502566afb312f2ff4ae7fcdd Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 6 Jun 2020 22:21:47 +0200 Subject: [PATCH 48/50] .gitlab-ci.yml: add Qemu tests for MIPS Malta board Add Qemu tests for the MIPS Malta machine as a replacement for the deprecated generic MIPS machine. Signed-off-by: Daniel Schwierzeck --- .gitlab-ci.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f2e491c117..a685a7879d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -276,6 +276,38 @@ qemu_mips64el test.py: TEST_PY_TEST_SPEC: "not sleep" <<: *buildman_and_testpy_dfn +qemu_malta test.py: + tags: [ 'all' ] + variables: + TEST_PY_BD: "malta" + TEST_PY_TEST_SPEC: "not sleep and not efi" + TEST_PY_ID: "--id qemu" + <<: *buildman_and_testpy_dfn + +qemu_maltael test.py: + tags: [ 'all' ] + variables: + TEST_PY_BD: "maltael" + TEST_PY_TEST_SPEC: "not sleep and not efi" + TEST_PY_ID: "--id qemu" + <<: *buildman_and_testpy_dfn + +qemu_malta64 test.py: + tags: [ 'all' ] + variables: + TEST_PY_BD: "malta64" + TEST_PY_TEST_SPEC: "not sleep and not efi" + TEST_PY_ID: "--id qemu" + <<: *buildman_and_testpy_dfn + +qemu_malta64el test.py: + tags: [ 'all' ] + variables: + TEST_PY_BD: "malta64el" + TEST_PY_TEST_SPEC: "not sleep and not efi" + TEST_PY_ID: "--id qemu" + <<: *buildman_and_testpy_dfn + qemu-ppce500 test.py: tags: [ 'all' ] variables: From d985aaa58e351e754bff66c386ad7d5e8a06ca09 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 6 Jun 2020 22:21:47 +0200 Subject: [PATCH 49/50] .travis.yml: add Qemu tests for MIPS Malta board Add Qemu tests for the MIPS Malta machine as a replacement for the deprecated generic MIPS machine. Signed-off-by: Daniel Schwierzeck --- .travis.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.travis.yml b/.travis.yml index bb02b6d816..a042aa2c7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -573,6 +573,34 @@ matrix: TEST_PY_TEST_SPEC="not sleep" QEMU_TARGET="mips64el-softmmu" TOOLCHAIN="mips" + - name: "test/py qemu-malta" + env: + - TEST_PY_BD="malta" + TEST_PY_TEST_SPEC="not sleep and not efi" + TEST_PY_ID="--id qemu" + QEMU_TARGET="mips-softmmu" + TOOLCHAIN="mips" + - name: "test/py qemu-maltael" + env: + - TEST_PY_BD="maltael" + TEST_PY_TEST_SPEC="not sleep and not efi" + TEST_PY_ID="--id qemu" + QEMU_TARGET="mipsel-softmmu" + TOOLCHAIN="mips" + - name: "test/py qemu-malta64" + env: + - TEST_PY_BD="malta64" + TEST_PY_TEST_SPEC="not sleep and not efi" + TEST_PY_ID="--id qemu" + QEMU_TARGET="mips64-softmmu" + TOOLCHAIN="mips" + - name: "test/py qemu-malta64el" + env: + - TEST_PY_BD="malta64el" + TEST_PY_TEST_SPEC="not sleep and not efi" + TEST_PY_ID="--id qemu" + QEMU_TARGET="mips64el-softmmu" + TOOLCHAIN="mips" - name: "test/py qemu-ppce500" env: - TEST_PY_BD="qemu-ppce500" From e35c2a8fdd41a34c06c409ce700c5d5591429367 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 6 Jun 2020 22:21:47 +0200 Subject: [PATCH 50/50] .azure-pipelines.yml: add Qemu tests for MIPS Malta board Add Qemu tests for the MIPS Malta machine as a replacement for the deprecated generic MIPS machine. Signed-off-by: Daniel Schwierzeck --- .azure-pipelines.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 28387ce17c..9f88a539c0 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -226,6 +226,22 @@ jobs: qemu_mips64el: TEST_PY_BD: "qemu_mips64el" TEST_PY_TEST_SPEC: "not sleep" + qemu_malta: + TEST_PY_BD: "malta" + TEST_PY_ID: "--id qemu" + TEST_PY_TEST_SPEC: "not sleep and not efi" + qemu_maltael: + TEST_PY_BD: "maltael" + TEST_PY_ID: "--id qemu" + TEST_PY_TEST_SPEC: "not sleep and not efi" + qemu_malta64: + TEST_PY_BD: "malta64" + TEST_PY_ID: "--id qemu" + TEST_PY_TEST_SPEC: "not sleep and not efi" + qemu_malta64el: + TEST_PY_BD: "malta64el" + TEST_PY_ID: "--id qemu" + TEST_PY_TEST_SPEC: "not sleep and not efi" qemu_ppce500: TEST_PY_BD: "qemu-ppce500" TEST_PY_TEST_SPEC: "not sleep"