From 1856bbe0c5fdf6ac388edc335e3e6f292f37929d Mon Sep 17 00:00:00 2001 From: zuoqian Date: Wed, 24 Apr 2024 10:30:01 +0800 Subject: [PATCH 01/71] spi: phytium: Fix phytium_spi_irq panic on boot The root cause is that irq is triggered between request_irq and spi_master_set devdata, and fts has not been initialized yet. Signed-off-by: Liu Dalin Tested-by: Peng Min --- drivers/spi/spi-phytium.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-phytium.c b/drivers/spi/spi-phytium.c index 78180523c02..be7073a3e35 100644 --- a/drivers/spi/spi-phytium.c +++ b/drivers/spi/spi-phytium.c @@ -403,6 +403,8 @@ int phytium_spi_add_host(struct device *dev, struct phytium_spi *fts) fts->dma_addr = (dma_addr_t)(fts->paddr + DR); snprintf(fts->name, sizeof(fts->name), "phytium_spi%d", fts->bus_num); + spi_hw_init(dev, fts); + ret = request_irq(fts->irq, phytium_spi_irq, IRQF_SHARED, fts->name, master); if (ret < 0) { dev_err(dev, "can not get IRQ\n"); @@ -424,8 +426,6 @@ int phytium_spi_add_host(struct device *dev, struct phytium_spi *fts) master->dev.fwnode = dev->fwnode; master->flags = SPI_CONTROLLER_GPIO_SS; - spi_hw_init(dev, fts); - if (fts->dma_ops && fts->dma_ops->dma_init) { ret = fts->dma_ops->dma_init(dev, fts); if (ret) { -- Gitee From a1d15f2f5218eccf15a5f8049f1cd82c731d3412 Mon Sep 17 00:00:00 2001 From: Wang Yinfeng Date: Wed, 7 Feb 2024 08:35:15 +0800 Subject: [PATCH 02/71] Phytium: merge some commit from 6.6.0.1 Most of commits are duplicate and only change MAINAINERS file. Just squash these commits. --- MAINTAINERS | 60 +++++++++++ arch/arm64/configs/defconfig | 1 + drivers/char/ipmi/kcs_bmc_phytium.c | 155 +++++++++++++++++++++++----- drivers/mmc/host/phytium-mci.c | 4 +- drivers/tee/optee/smc_abi.c | 2 +- drivers/usb/phytium/Kconfig | 11 ++ drivers/usb/phytium/Makefile | 2 + sound/soc/phytium/Kconfig | 2 +- 8 files changed, 205 insertions(+), 32 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f04460ea148..2bfff87318b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17482,6 +17482,66 @@ F: include/sound/pxa2xx-lib.h F: sound/arm/pxa* F: sound/soc/pxa/ +ARM/PHYTIUM SOC SUPPORT +M: Wang Yinfeng +S: Maintained +W: https://www.phytium.com.cn +F: Documentation/devicetree/bindings/gpio/phytium,gpio.yaml +F: Documentation/devicetree/bindings/gpio/phytium,sgpio.yaml +F: drivers/hwmon/tacho-phytium.c +F: Documentation/devicetree/bindings/hwlock/phytium,hwspinlock.yaml +F: Documentation/devicetree/bindings/hwmon/phytium,tacho.yaml +F: Documentation/devicetree/bindings/i2c/phytium,i2c.yaml +F: Documentation/devicetree/bindings/media/phytium,jpeg.yaml +F: Documentation/devicetree/bindings/iio/adc/phytium,adc.yaml +F: Documentation/devicetree/bindings/input/phytium,keypad.yaml +F: Documentation/devicetree/bindings/interrupt-controller/phytium,ixic.yaml +F: Documentation/devicetree/bindings/ipmi/phytium,bt-bmc.yaml +F: Documentation/devicetree/bindings/ipmi/phytium,kcs-bmc.yaml +F: Documentation/devicetree/bindings/mailbox/phytium,mbox.yaml +F: Documentation/devicetree/bindings/mmc/phytium,mci.yaml +F: Documentation/devicetree/bindings/mmc/phytium,sdci.yaml +F: Documentation/devicetree/bindings/mtd/phytium,nfc.yaml +F: Documentation/devicetree/bindings/net/can/phytium,can.yaml +F: Documentation/devicetree/bindings/pci/phytium,pd2008-pcie-ep.yaml +F: Documentation/devicetree/bindings/pwm/phytium,pwm.yaml +F: Documentation/devicetree/bindings/rng/phytium,rng.yaml +F: Documentation/devicetree/bindings/sound/phytium,hda.yaml +F: Documentation/devicetree/bindings/sound/phytium,i2s.yaml +F: Documentation/devicetree/bindings/spi/phytium,qspi-nor.yaml +F: Documentation/devicetree/bindings/spi/phytium,spi.yaml +F: Documentation/devicetree/bindings/usb/phytium,usb2.yaml +F: Documentation/devicetree/bindings/w1/phytium,w1.yaml +F: arch/arm64/boot/dts/phytium/* +F: drivers/char/hw_random/phytium-rng.c +F: drivers/char/ipmi/bt_bmc_phytium.c +F: drivers/char/ipmi/kcs_bmc_phytium.c +F: drivers/gpio/gpio-phytium* +F: drivers/gpio/gpio-phytium-sgpio.c +F: drivers/hwspinlock/phytium_hwspinlock.c +F: drivers/i2c/busses/i2c-phytium-* +F: drivers/iio/adc/phytium-adc.c +F: drivers/input/keyboard/phytium-keypad.c +F: drivers/input/serio/phytium-ps2.c +F: drivers/irqchip/irq-phytium-ixic.c +F: drivers/mailbox/phytium_mailbox.c +F: drivers/media/platform/phytium-jpeg/phytium_jpeg* +F: drivers/mfd/phytium_px210_i2s_lsd.c +F: drivers/mfd/phytium_px210_i2s_mmd.c +F: drivers/mmc/host/phytium-mci* +F: drivers/mmc/host/phytium-sdci.* +F: drivers/mtd/nand/raw/phytium_nand* +F: drivers/net/can/phytium/* +F: drivers/pci/controller/pcie-phytium* +F: drivers/pwm/pwm-phytium.c +F: drivers/spi/spi-phytium* +F: drivers/spi/spi-phytium-qspi.c +F: drivers/tty/serial/phytium-uart.c +F: drivers/usb/phytium/* +F: drivers/w1/masters/phytium_w1.c +F: sound/pci/hda/hda_phytium.* +F: sound/soc/phytium/* + QAT DRIVER M: Giovanni Cabiddu L: qat-linux@intel.com diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index a789119e648..0fd77961c63 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -55,6 +55,7 @@ CONFIG_ARCH_MXC=y CONFIG_ARCH_S32=y CONFIG_ARCH_MA35=y CONFIG_ARCH_NPCM=y +CONFIG_ARCH_PHYTIUM=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_REALTEK=y CONFIG_ARCH_RENESAS=y diff --git a/drivers/char/ipmi/kcs_bmc_phytium.c b/drivers/char/ipmi/kcs_bmc_phytium.c index e26162e395a..ddbe363bfa5 100644 --- a/drivers/char/ipmi/kcs_bmc_phytium.c +++ b/drivers/char/ipmi/kcs_bmc_phytium.c @@ -12,9 +12,12 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -82,13 +85,26 @@ #define LPC_ODR4 0x90 #define LPC_STR4 0x94 +#define OBE_POLL_PERIOD (HZ / 2) struct phytium_kcs_bmc { struct kcs_bmc_device kcs_bmc; struct regmap *map; + + struct { + spinlock_t lock; + bool remove; + struct timer_list timer; + } obe; +}; + +struct phytium_kcs_of_ops { + int (*get_channel)(struct platform_device *pdev); + int (*get_io_address)(struct platform_device *pdev, u32 addr); }; -static inline struct phytium_kcs_bmc *to_phytium_kcs_bmc(struct kcs_bmc_device *kcs_bmc) +static inline struct phytium_kcs_bmc *to_phytium_kcs_bmc + (struct kcs_bmc_device *kcs_bmc) { return container_of(kcs_bmc, struct phytium_kcs_bmc, kcs_bmc); } @@ -114,6 +130,14 @@ static void phytium_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data) WARN(rc != 0, "regmap_write() failed: %d\n", rc); } +static void phytium_kcs_updateb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 mask, u8 val) +{ + struct phytium_kcs_bmc *priv = to_phytium_kcs_bmc(kcs_bmc); + int rc; + + rc = regmap_update_bits(priv->map, reg, mask, val); + WARN(rc != 0, "regmap_update_bits() failed: %d\n", rc); +} /* * Background: * we note D for Data, and C for Cmd/Status, default rules are @@ -127,11 +151,11 @@ static void phytium_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data) * D / C : CA4h / CA5h * D / C : CB0h / CB1h -use */ -static void phytium_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u16 addr) +static int phytium_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u16 addr) { struct phytium_kcs_bmc *priv = to_phytium_kcs_bmc(kcs_bmc); - switch (kcs_bmc->channel) { + switch (priv->kcs_bmc.channel) { case 1: regmap_update_bits(priv->map, LPC_HICR4, LPC_HICR4_LADR12AS, 0); regmap_write(priv->map, LPC_LADR12H, addr >> 8); @@ -154,6 +178,7 @@ static void phytium_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u16 addr) default: break; } + return 0; } static void phytium_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enable) @@ -163,34 +188,24 @@ static void phytium_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enab switch (kcs_bmc->channel) { case 1: if (enable) { - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF1, LPC_HICR2_IBFIF1); regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC1E, LPC_HICR0_LPC1E); } else { regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC1E, 0); - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF1, 0); } break; case 2: if (enable) { - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF2, LPC_HICR2_IBFIF2); regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC2E, LPC_HICR0_LPC2E); } else { regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC2E, 0); - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF2, 0); } break; case 3: if (enable) { - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF3, LPC_HICR2_IBFIF3); regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC3E, LPC_HICR0_LPC3E); regmap_update_bits(priv->map, LPC_HICR4, @@ -200,8 +215,6 @@ static void phytium_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enab LPC_HICR0_LPC3E, 0); regmap_update_bits(priv->map, LPC_HICR4, LPC_HICR4_KCSENBL, 0); - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF3, 0); } break; case 4: @@ -215,13 +228,78 @@ static void phytium_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enab 0); break; default: - break; + pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel); + return; + } +} + +static void phytium_kcs_check_obe(struct timer_list *timer) +{ + struct phytium_kcs_bmc *priv = container_of(timer, struct phytium_kcs_bmc, obe.timer); + unsigned long flags; + u8 str; + + spin_lock_irqsave(&priv->obe.lock, flags); + if (priv->obe.remove) { + spin_unlock_irqrestore(&priv->obe.lock, flags); + return; + } + + str = phytium_kcs_inb(&priv->kcs_bmc, priv->kcs_bmc.ioreg.str); + if (str & KCS_BMC_STR_OBF) { + mod_timer(timer, jiffies + OBE_POLL_PERIOD); + spin_unlock_irqrestore(&priv->obe.lock, flags); + return; + } + spin_unlock_irqrestore(&priv->obe.lock, flags); + + kcs_bmc_handle_event(&priv->kcs_bmc); +} + +static void phytium_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state) +{ + struct phytium_kcs_bmc *priv = to_phytium_kcs_bmc(kcs_bmc); + + if (mask & KCS_BMC_EVENT_TYPE_OBE) { + if (KCS_BMC_EVENT_TYPE_OBE & state) + mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD); + else + del_timer(&priv->obe.timer); + } + + if (mask & KCS_BMC_EVENT_TYPE_IBF) { + const bool enable = !!(state & KCS_BMC_EVENT_TYPE_IBF); + + switch (kcs_bmc->channel) { + case 1: + regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIF1, + enable * LPC_HICR2_IBFIF1); + return; + case 2: + regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIF2, + enable * LPC_HICR2_IBFIF2); + return; + case 3: + regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIF3, + enable * LPC_HICR2_IBFIF3); + return; + case 4: + regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_IBFIF4, + enable * LPC_HICRB_IBFIF4); + return; + default: + pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel); + return; + } } } + static const struct kcs_bmc_device_ops phytium_kcs_ops = { + .irq_mask_update = phytium_kcs_irq_mask_update, .io_inputb = phytium_kcs_inb, .io_outputb = phytium_kcs_outb, + .io_updateb = phytium_kcs_updateb, }; static irqreturn_t phytium_kcs_irq(int irq, void *arg) @@ -231,7 +309,8 @@ static irqreturn_t phytium_kcs_irq(int irq, void *arg) return kcs_bmc_handle_event(kcs_bmc); } -static int phytium_kcs_config_irq(struct kcs_bmc_device *kcs_bmc, struct platform_device *pdev) +static int phytium_kcs_config_irq(struct kcs_bmc_device *kcs_bmc, + struct platform_device *pdev) { struct device *dev = &pdev->dev; int irq; @@ -249,6 +328,7 @@ static const struct kcs_ioreg phytium_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = { { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 }, { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 }, { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }, + }; static int phytium_kcs_probe(struct platform_device *pdev) @@ -256,6 +336,7 @@ static int phytium_kcs_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phytium_kcs_bmc *priv; struct kcs_bmc_device *kcs_bmc; + struct device_node *np; u32 chan, addr; int rc; @@ -264,45 +345,57 @@ static int phytium_kcs_probe(struct platform_device *pdev) dev_err(dev, "no valid 'kcs_chan' configured\n"); return -ENODEV; } - rc = of_property_read_u32(dev->of_node, "kcs_addr", &addr); if (rc) { dev_err(dev, "no valid 'kcs_addr' configured\n"); return -ENODEV; } + np = pdev->dev.of_node; + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; kcs_bmc = &priv->kcs_bmc; - kcs_bmc->dev = dev; + kcs_bmc->dev = &pdev->dev; kcs_bmc->channel = chan; kcs_bmc->ioreg = phytium_kcs_bmc_ioregs[chan - 1]; kcs_bmc->ops = &phytium_kcs_ops; - priv->map = syscon_node_to_regmap(dev->parent->of_node); + priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node); if (IS_ERR(priv->map)) { - dev_err(dev, "Couldn't get regmap\n"); + dev_err(&pdev->dev, "Couldn't get regmap\n"); return -ENODEV; } - platform_set_drvdata(pdev, priv); + spin_lock_init(&priv->obe.lock); + priv->obe.remove = false; + timer_setup(&priv->obe.timer, phytium_kcs_check_obe, 0); + + rc = phytium_kcs_set_address(kcs_bmc, addr); + if (rc) + return rc; - phytium_kcs_set_address(kcs_bmc, addr); - phytium_kcs_enable_channel(kcs_bmc, true); rc = phytium_kcs_config_irq(kcs_bmc, pdev); if (rc) return rc; + platform_set_drvdata(pdev, priv); + + phytium_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), 0); + + phytium_kcs_enable_channel(kcs_bmc, true); + rc = kcs_bmc_add_device(&priv->kcs_bmc); if (rc) { - dev_err(dev, "Unable to register device\n"); + dev_warn(&pdev->dev, "Failed to register channel %d: %d\n", + kcs_bmc->channel, rc); return rc; } - pr_info("channel=%u addr=0x%x idr=0x%x odr=0x%x str=0x%x\n", - chan, addr, kcs_bmc->ioreg.idr, kcs_bmc->ioreg.odr, kcs_bmc->ioreg.str); + dev_info(&pdev->dev, "Initialised channel %d at 0x%x\n", + kcs_bmc->channel, addr); return 0; } @@ -313,12 +406,18 @@ static int phytium_kcs_remove(struct platform_device *pdev) struct kcs_bmc_device *kcs_bmc = &priv->kcs_bmc; kcs_bmc_remove_device(kcs_bmc); + phytium_kcs_enable_channel(kcs_bmc, false); + phytium_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), 0); + spin_lock_irq(&priv->obe.lock); + priv->obe.remove = true; + spin_unlock_irq(&priv->obe.lock); + del_timer_sync(&priv->obe.timer); return 0; } static const struct of_device_id phytium_kcs_bmc_match[] = { - { .compatible = "phytium,kcs-bmc" }, + { .compatible = "phytium,kcs-bmc", }, { } }; MODULE_DEVICE_TABLE(of, phytium_kcs_bmc_match); diff --git a/drivers/mmc/host/phytium-mci.c b/drivers/mmc/host/phytium-mci.c index 5af8859ba6e..30918bfe6fe 100644 --- a/drivers/mmc/host/phytium-mci.c +++ b/drivers/mmc/host/phytium-mci.c @@ -134,7 +134,7 @@ static void phytium_mci_send_cmd(struct phytium_mci_host *host, u32 cmd, u32 arg rc = readl_relaxed_poll_timeout(host->base + MCI_STATUS, data, !(data & MCI_STATUS_CARD_BUSY), - 0, 100 * 1000); + 0, 5000 * 1000); if (rc == -ETIMEDOUT) pr_debug("%s %d, timeout mci_status: 0x%08x\n", __func__, __LINE__, data); @@ -143,7 +143,7 @@ static void phytium_mci_send_cmd(struct phytium_mci_host *host, u32 cmd, u32 arg rc = readl_relaxed_poll_timeout(host->base + MCI_CMD, data, !(data & MCI_CMD_START), - 0, 100 * 1000); + 0, 5000 * 1000); if (rc == -ETIMEDOUT) pr_debug("%s %d, timeout mci_cmd: 0x%08x\n", __func__, __LINE__, data); } diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index d1c1a0de5fb..e2b16275df1 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1428,7 +1428,7 @@ static void optee_smccc_hvc(unsigned long a0, unsigned long a1, #if defined(CONFIG_OPTEE_DEFAULT_METHOD_HVC) #define DEFAULT_CONDUIT_METHOD optee_smccc_hvc #elif defined(CONFIG_OPTEE_DEFAULT_METHOD_SMC) -#define DEFAULT_CONDUIT_METHOD optee_smccc_hvc +#define DEFAULT_CONDUIT_METHOD optee_smccc_smc #else #define DEFAULT_CONDUIT_METHOD ERR_PTR(-ENXIO) #endif diff --git a/drivers/usb/phytium/Kconfig b/drivers/usb/phytium/Kconfig index 7f28d666737..797d7b4ee10 100644 --- a/drivers/usb/phytium/Kconfig +++ b/drivers/usb/phytium/Kconfig @@ -7,3 +7,14 @@ config USB_PHYTIUM If you choose to build this driver is a dynamically linked modules, the module will be called phytium-usb.ko + +config USB_PHYTIUM_PCI + tristate "PHYTIUM PCI USB Support" + default n + depends on USB + depends on USB_GADGET + help + Say Y or M here if your system has a OTG USB Controller based on PHYTIUM SOC. + + If you choose to build this driver is a dynamically linked modules, the module will + be called phytium-usb-pci.ko diff --git a/drivers/usb/phytium/Makefile b/drivers/usb/phytium/Makefile index 05d422d4a59..e176c334cba 100644 --- a/drivers/usb/phytium/Makefile +++ b/drivers/usb/phytium/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_USB_PHYTIUM) += phytium-usb.o +obj-$(CONFIG_USB_PHYTIUM_PCI) += phytium-usb-pci.o phytium-usb-y := core.o dma.o platform.o host.o gadget.o +phytium-usb-pci-y := core.o dma.o pci.o host.o gadget.o diff --git a/sound/soc/phytium/Kconfig b/sound/soc/phytium/Kconfig index c0621dce122..b4fd9ae0b65 100644 --- a/sound/soc/phytium/Kconfig +++ b/sound/soc/phytium/Kconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 config SND_SOC_PHYTIUM_I2S - bool "Phytium I2S Device Driver" + tristate "Phytium I2S Device Driver" depends on ARCH_PHYTIUM help Say Y or M if you want to add support for I2S driver for -- Gitee From a29818a44fad8fdb484d61d7869e0200df1ef0ce Mon Sep 17 00:00:00 2001 From: Chen Baozi Date: Fri, 14 Jul 2023 08:34:22 +0800 Subject: [PATCH 03/71] watchdog: dw: Add ACPI support to dw-wdt Phytium Ps20064 SoC includes a designware watchdog which is non-SBSA compatible. Therefore, we put its description in DSDT with clock-frequency property given in _DSD object which is required by the driver. Signed-off-by: Wang Yinfeng Signed-off-by: Chen Baozi Change-Id: Ibf0a83924dbafad2c5997f45a0432ba541cd3831 --- drivers/watchdog/dw_wdt.c | 72 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 84dca3695f8..c444082e047 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -12,6 +12,7 @@ * heartbeat requests after the watchdog device has been closed. */ +#include #include #include #include @@ -83,7 +84,7 @@ struct dw_wdt { void __iomem *regs; struct clk *clk; struct clk *pclk; - unsigned long rate; + u64 rate; enum dw_wdt_rmod rmod; struct dw_wdt_timeout timeouts[DW_WDT_NUM_TOPS]; struct watchdog_device wdd; @@ -560,33 +561,45 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) if (IS_ERR(dw_wdt->regs)) return PTR_ERR(dw_wdt->regs); - /* - * Try to request the watchdog dedicated timer clock source. It must - * be supplied if asynchronous mode is enabled. Otherwise fallback - * to the common timer/bus clocks configuration, in which the very - * first found clock supply both timer and APB signals. - */ - dw_wdt->clk = devm_clk_get_enabled(dev, "tclk"); - if (IS_ERR(dw_wdt->clk)) { - dw_wdt->clk = devm_clk_get_enabled(dev, NULL); - if (IS_ERR(dw_wdt->clk)) - return PTR_ERR(dw_wdt->clk); - } + if (dev->of_node) { + /* + * Try to request the watchdog dedicated timer clock source. It must + * be supplied if asynchronous mode is enabled. Otherwise fallback + * to the common timer/bus clocks configuration, in which the very + * first found clock supply both timer and APB signals. + */ + dw_wdt->clk = devm_clk_get_enabled(dev, "tclk"); + if (IS_ERR(dw_wdt->clk)) { + dw_wdt->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(dw_wdt->clk)) + return PTR_ERR(dw_wdt->clk); + } - dw_wdt->rate = clk_get_rate(dw_wdt->clk); - if (dw_wdt->rate == 0) - return -EINVAL; + dw_wdt->rate = clk_get_rate(dw_wdt->clk); + if (dw_wdt->rate == 0) + return -EINVAL; - /* - * Request APB clock if device is configured with async clocks mode. - * In this case both tclk and pclk clocks are supposed to be specified. - * Alas we can't know for sure whether async mode was really activated, - * so the pclk phandle reference is left optional. If it couldn't be - * found we consider the device configured in synchronous clocks mode. - */ - dw_wdt->pclk = devm_clk_get_optional_enabled(dev, "pclk"); - if (IS_ERR(dw_wdt->pclk)) - return PTR_ERR(dw_wdt->pclk); + /* + * Request APB clock if device is configured with async clocks mode. + * In this case both tclk and pclk clocks are supposed to be specified. + * Alas we can't know for sure whether async mode was really activated, + * so the pclk phandle reference is left optional. If it couldn't be + * found we consider the device configured in synchronous clocks mode. + */ + dw_wdt->pclk = devm_clk_get_optional_enabled(dev, "pclk"); + if (IS_ERR(dw_wdt->pclk)) + return PTR_ERR(dw_wdt->pclk); + } else if (has_acpi_companion(&pdev->dev)) { + /* + * When Driver probe with ACPI device, clock devices + * are not available, so watchdog rate get from + * clock-frequency property given in _DSD object. + */ + device_property_read_u64(dev, "clock-frequency", + &dw_wdt->rate); + if (dw_wdt->rate == 0) + return -EINVAL; + } dw_wdt->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL); if (IS_ERR(dw_wdt->rst)) @@ -674,6 +687,12 @@ static void dw_wdt_drv_remove(struct platform_device *pdev) reset_control_assert(dw_wdt->rst); } +static const struct acpi_device_id dw_wdt_acpi_match[] = { + { "PHYT0014", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, dw_wdt_acpi_match); + #ifdef CONFIG_OF static const struct of_device_id dw_wdt_of_match[] = { { .compatible = "snps,dw-wdt", }, @@ -688,6 +707,7 @@ static struct platform_driver dw_wdt_driver = { .driver = { .name = "dw_wdt", .of_match_table = of_match_ptr(dw_wdt_of_match), + .acpi_match_table = ACPI_PTR(dw_wdt_acpi_match), .pm = pm_sleep_ptr(&dw_wdt_pm_ops), }, }; -- Gitee From 45d83206d99df5bf356fe145461538eaa6e4c87f Mon Sep 17 00:00:00 2001 From: Liu Tianyu Date: Wed, 20 Mar 2024 14:11:55 +0800 Subject: [PATCH 04/71] dt-bindings: phytium-ddma: Add bindings for Phytium DDMA This patch document provide DT bindings for the Phytium DDMA controller. Signed-off-by: Liu Tianyu Signed-off-by: Li Mingzhe Signed-off-by: Wang Yinfeng Signed-off-by: Lan Hengyu Change-Id: Ia72f3a6d2d42b895cc488f3e402d3452e6a085f6 --- .../devicetree/bindings/dma/phytium-ddma.yaml | 57 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 58 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/phytium-ddma.yaml diff --git a/Documentation/devicetree/bindings/dma/phytium-ddma.yaml b/Documentation/devicetree/bindings/dma/phytium-ddma.yaml new file mode 100644 index 00000000000..098dbd867a1 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/phytium-ddma.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +title: Phytium DDMA Controller bindings + +description: +The Phytium DDMA is a general-purpose direct memory access +controller capable of supporting 8 independent DMA channels. +Each channel can have up to 32 requests.DMA clients connected +to the Phytium DDMA controller must use the format described +in the dma.txt file, using a two-cell specifier for each +channel: + a phandle to the DMA controller plus the following two integer cells: + 1. The channel id + 2. The request line number + +maintainers: + - Huang Jie + +allOf: + - $ref: "dma-controller.yaml#" + +properties: + "#dma-cells": + const: 2 + + compatible: + const: phytium,ddma + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + dma-channels: + minItems: 1 + maxItems: 8 + description: it indicates that the number of channels are used + +required: + - compatible + - reg + - interrupts + - dma-channels + +unevaluatedProperties: false + +examples: + ddma0: ddma@28003000 { + compatible = "phytium,ddma"; + reg = <0x0 0x28003000 0x0 0x1000>; + interrupts = ; + #dma-cells = <2>; + dma-channels = <8>; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 2bfff87318b..79e25d2719e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17486,6 +17486,7 @@ ARM/PHYTIUM SOC SUPPORT M: Wang Yinfeng S: Maintained W: https://www.phytium.com.cn +F: Documentation/devicetree/bindings/dma/phytium-ddma.yaml F: Documentation/devicetree/bindings/gpio/phytium,gpio.yaml F: Documentation/devicetree/bindings/gpio/phytium,sgpio.yaml F: drivers/hwmon/tacho-phytium.c -- Gitee From dd8c79d745063e081012efa6517da5c6707eaebf Mon Sep 17 00:00:00 2001 From: Zhu Honglei Date: Wed, 20 Mar 2024 14:53:55 +0800 Subject: [PATCH 05/71] edac: Phytium: Add edac driver to receive RAS error Support for error detection and correction on the Phytium Pe220x family of SOCs. Signed-off-by: Zhu Honglei Signed-off-by: Lan Hengyu Signed-off-by: Li Mingzhe Signed-off-by: Wang Yinfeng Change-Id: Iaa02a12427e8a032e12dcf148da9b6deb574a2f6 --- MAINTAINERS | 70 +----- drivers/edac/Kconfig | 7 + drivers/edac/Makefile | 1 + drivers/edac/phytium_edac.c | 481 ++++++++++++++++++++++++++++++++++++ 4 files changed, 492 insertions(+), 67 deletions(-) create mode 100644 drivers/edac/phytium_edac.c diff --git a/MAINTAINERS b/MAINTAINERS index 79e25d2719e..e02a06d96a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2526,73 +2526,6 @@ S: Maintained W: http://www.digriz.org.uk/ts78xx/kernel F: arch/arm/mach-orion5x/ts78xx-* -ARM/PHYTIUM SOC SUPPORT -M: Chen Baozi -S: Maintained -W: https://www.phytium.com.cn -F: Documentation/devicetree/bindings/dma/phytium,ddma.yaml -F: Documentation/devicetree/bindings/gpio/phytium,pe220x-edac.yaml -F: Documentation/devicetree/bindings/gpio/phytium,gpio.yaml -F: Documentation/devicetree/bindings/gpio/phytium,sgpio.yaml -F: Documentation/devicetree/bindings/gpu/phytium,dc.yaml -F: Documentation/devicetree/bindings/hwlock/phytium,hwspinlock.yaml -F: Documentation/devicetree/bindings/hwmon/phytium,tacho.yaml -F: Documentation/devicetree/bindings/i2c/phytium,i2c.yaml -F: Documentation/devicetree/bindings/media/phytium,jpeg.yaml -F: Documentation/devicetree/bindings/iio/adc/phytium,adc.yaml -F: Documentation/devicetree/bindings/input/phytium,keypad.yaml -F: Documentation/devicetree/bindings/interrupt-controller/phytium,ixic.yaml -F: Documentation/devicetree/bindings/ipmi/phytium,bt-bmc.yaml -F: Documentation/devicetree/bindings/ipmi/phytium,kcs-bmc.yaml -F: Documentation/devicetree/bindings/mailbox/phytium,mbox.yaml -F: Documentation/devicetree/bindings/mmc/phytium,mci.yaml -F: Documentation/devicetree/bindings/mmc/phytium,sdci.yaml -F: Documentation/devicetree/bindings/mtd/phytium,nfc.yaml -F: Documentation/devicetree/bindings/net/can/phytium,can.yaml -F: Documentation/devicetree/bindings/pci/phytium,pd2008-pcie-ep.yaml -F: Documentation/devicetree/bindings/pwm/phytium,pwm.yaml -F: Documentation/devicetree/bindings/rng/phytium,rng.yaml -F: Documentation/devicetree/bindings/sound/phytium,hda.yaml -F: Documentation/devicetree/bindings/sound/phytium,i2s.yaml -F: Documentation/devicetree/bindings/spi/phytium,qspi-nor.yaml -F: Documentation/devicetree/bindings/spi/phytium,spi.yaml -F: Documentation/devicetree/bindings/usb/phytium,usb2.yaml -F: Documentation/devicetree/bindings/w1/phytium,w1.yaml -F: arch/arm64/boot/dts/phytium/* -F: drivers/char/hw_random/phytium-rng.c -F: drivers/char/ipmi/bt_bmc_phytium.c -F: drivers/char/ipmi/kcs_bmc_phytium.c -F: drivers/dma/phytium/phytium-ddmac.c -F: drivers/edac/phytium_pe220x_edac.c -F: drivers/gpio/gpio-phytium* -F: drivers/gpio/gpio-phytium-sgpio.c -F: drivers/gpu/drm/phytium/* -F: drivers/hwmon/tacho-phytium.c -F: drivers/hwspinlock/phytium_hwspinlock.c -F: drivers/i2c/busses/i2c-phytium-* -F: drivers/iio/adc/phytium-adc.c -F: drivers/input/keyboard/phytium-keypad.c -F: drivers/input/serio/phytium-ps2.c -F: drivers/irqchip/irq-phytium-ixic.c -F: drivers/mailbox/phytium_mailbox.c -F: drivers/media/platform/phytium-jpeg/phytium_jpeg* -F: drivers/mfd/phytium_px210_i2s_lsd.c -F: drivers/mfd/phytium_px210_i2s_mmd.c -F: drivers/mmc/host/phytium-mci* -F: drivers/mmc/host/phytium-sdci.* -F: drivers/mtd/nand/raw/phytium_nand* -F: drivers/net/can/phytium/* -F: drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c -F: drivers/pci/controller/pcie-phytium* -F: drivers/pwm/pwm-phytium.c -F: drivers/spi/spi-phytium* -F: drivers/spi/spi-phytium-qspi.c -F: drivers/tty/serial/phytium-uart.c -F: drivers/usb/phytium/* -F: drivers/w1/masters/phytium_w1.c -F: sound/pci/hda/hda_phytium.* -F: sound/soc/phytium/* - ARM/QUALCOMM CHROMEBOOK SUPPORT R: cros-qcom-dts-watchers@chromium.org F: arch/arm64/boot/dts/qcom/sc7180* @@ -17487,6 +17420,7 @@ M: Wang Yinfeng S: Maintained W: https://www.phytium.com.cn F: Documentation/devicetree/bindings/dma/phytium-ddma.yaml +F: Documentation/devicetree/bindings/edac/phytium-pe220x-edac.txt F: Documentation/devicetree/bindings/gpio/phytium,gpio.yaml F: Documentation/devicetree/bindings/gpio/phytium,sgpio.yaml F: drivers/hwmon/tacho-phytium.c @@ -17517,6 +17451,8 @@ F: arch/arm64/boot/dts/phytium/* F: drivers/char/hw_random/phytium-rng.c F: drivers/char/ipmi/bt_bmc_phytium.c F: drivers/char/ipmi/kcs_bmc_phytium.c +F: drivers/dma/phytium/phytium-ddmac.c +F: drivers/edac/phytium_edac.c F: drivers/gpio/gpio-phytium* F: drivers/gpio/gpio-phytium-sgpio.c F: drivers/hwspinlock/phytium_hwspinlock.c diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 025b6ee672b..69b71c803e6 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -505,6 +505,13 @@ config EDAC_TI help Support for error detection and correction on the TI SoCs. +config EDAC_PHYTIUM + tristate "Phytium Pe220x SoC" + depends on (ARM64) + help + Support for error detection and correction on the + Phytium Pe220x family of SOCs. + config EDAC_QCOM tristate "QCOM EDAC Controller" depends on ARCH_QCOM && QCOM_LLCC diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index b45c72a6a5b..d3caedd416b 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_EDAC_ARMADA_XP) += armada_xp_edac.o obj-$(CONFIG_EDAC_SYNOPSYS) += synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o obj-$(CONFIG_EDAC_TI) += ti_edac.o +obj-$(CONFIG_EDAC_PHYTIUM) += phytium_edac.o obj-$(CONFIG_EDAC_QCOM) += qcom_edac.o obj-$(CONFIG_EDAC_ASPEED) += aspeed_edac.o obj-$(CONFIG_EDAC_BLUEFIELD) += bluefield_edac.o diff --git a/drivers/edac/phytium_edac.c b/drivers/edac/phytium_edac.c new file mode 100644 index 00000000000..af6a729816f --- /dev/null +++ b/drivers/edac/phytium_edac.c @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Phytium Pe220x EDAC (error detection and correction) + * + * Copyright (c) 2019-2023, Phytium Technology Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "edac_module.h" + +#define EDAC_MOD_STR "phytium_edac" + +/* register offset */ +#define ERR_STATUS(n) (0x10 + ((n) * 64)) +#define ERR_CTLR(n) (0x08 + ((n) * 64)) +#define ERR_MISC0(n) (0x20 + ((n) * 64)) +#define ERR_INJECT 0x7C +#define ERR_DEVID 0xFC8 +#define ERR_GSR 0xE00 + +#define CTLR_ED BIT(0) +#define CTLR_UI BIT(2) +#define CTLR_CFI BIT(8) + +#define MISC0_CEC(x) ((u64)(x) << 32) + +#define ERR_STATUS_CLEAR GENMASK(31, 0) + +#define CORRECTED_ERROR 0 +#define UNCORRECTED_ERROR 1 + +#define MAX_ERR_GROUP 3 + +struct phytium_edac { + struct device *dev; + void __iomem **ras_base; + struct dentry *dfs; + struct edac_device_ctl_info *edac_dev; +}; + +struct ras_error_info { + u32 index; + u32 error_type; + const char *error_str; +}; + +/* error severity definition */ +enum { + SEV_NO = 0x0, + SEV_CORRECTED = 0x1, + SEV_RECOVERABLE = 0x2, + SEV_PANIC = 0x3, +}; + +/* soc error record */ +static const struct ras_error_info pe220x_ras_soc_error[] = { + { 0, UNCORRECTED_ERROR, "lsd_nfc_ras_error" }, + { 1, UNCORRECTED_ERROR, "lsd_lpc_ras_long_wait_to" }, + { 2, UNCORRECTED_ERROR, "lsd_lpc_ras_short_wait_to" }, + { 3, UNCORRECTED_ERROR, "lsd_lpc_ras_sync_err" }, + { 4, UNCORRECTED_ERROR, "lsd_lbc_ras_err" }, + { 5, UNCORRECTED_ERROR, "usb3_err_0" }, + { 6, UNCORRECTED_ERROR, "usb3_err_1" }, + { 7, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_nonfatal_int" }, + { 8, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_fatal_int" }, + { 9, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_trans_to_err" }, + { 10, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_protocol_err" }, + { 11, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_nonfatal_int" }, + { 12, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_fatal_int" }, + { 13, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_trans_to_err" }, + { 14, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_protocol_err" }, + { 15, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_nonfatal_int" }, + { 16, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_fatal_int" }, + { 17, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_trans_to_err" }, + { 18, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_protocol_err" }, + { 19, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_nonfatal_int" }, + { 20, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_fatal_int" }, + { 21, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_trans_to_err" }, + { 22, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_protocol_err" }, + { 23, CORRECTED_ERROR, "dmu_ras_ecc_corrected_error" }, + { 24, UNCORRECTED_ERROR, "dmu_ras_ecc_uncorrected_error" }, + { 25, UNCORRECTED_ERROR, "cci_ras_nERRIRQ" }, + { 26, UNCORRECTED_ERROR, "smmu_tcu_ras_irpt" }, + { 27, UNCORRECTED_ERROR, "smmu_tbu0_ras_irpt" }, + { 28, UNCORRECTED_ERROR, "smmu_tbu1_ras_irpt" }, + { 29, UNCORRECTED_ERROR, "smmu_tbu2_ras_irpt" }, + { 30, UNCORRECTED_ERROR, "ocm_sram_ue" }, + { 31, CORRECTED_ERROR, "ocm_sram_ce" }, + { 32, UNCORRECTED_ERROR, "int_axim_err" }, + { 33, UNCORRECTED_ERROR, "int_fatal_error" }, + { 34, UNCORRECTED_ERROR, "nEXTERRIRQ_clust0" }, + { 35, UNCORRECTED_ERROR, "nINTERRIRQ_clust0" }, + { 36, UNCORRECTED_ERROR, "nEXTERRIRQ_clust1" }, + { 37, UNCORRECTED_ERROR, "nINTERRIRQ_clust1" }, + { 38, UNCORRECTED_ERROR, "nEXTERRIRQ_clust2" }, + { 39, UNCORRECTED_ERROR, "nINTERRIRQ_clust2" }, + { 40, UNCORRECTED_ERROR, "ams_ame0_ras_err" }, + { 41, UNCORRECTED_ERROR, "ams_ame1_ras_err" }, + { 42, UNCORRECTED_ERROR, "ams_amer_ras_err" }, + { 43, UNCORRECTED_ERROR, "ras_err_ame1" }, +}; + +/* pcie controller error record */ +static const struct ras_error_info pe220x_ras_peu_psu_error[] = { + { 0, CORRECTED_ERROR, "pio_rd_addr_error" }, + { 1, UNCORRECTED_ERROR, "pio_wr_addr_error" }, + { 2, CORRECTED_ERROR, "pio_rd_timeout" }, + { 3, CORRECTED_ERROR, "pio_wr_timeout" }, + { 4, CORRECTED_ERROR, "axi_b_rsp_error" }, + { 5, CORRECTED_ERROR, "axi_r_rsp_error" }, +}; + +static const struct ras_error_info pe220x_ras_peu_error[] = { + { 0, CORRECTED_ERROR, "pio_rd_addr_error" }, + { 1, UNCORRECTED_ERROR, "pio_wr_addr_error" }, + { 2, CORRECTED_ERROR, "pio_rd_timeout" }, + { 3, CORRECTED_ERROR, "pio_wr_timeout" }, + { 4, CORRECTED_ERROR, "axi_b_rsp_error" }, + { 5, CORRECTED_ERROR, "axi_r_rsp_error" }, +}; + +static const struct ras_error_info *pe220x_ras_error[] = { + pe220x_ras_soc_error, pe220x_ras_peu_psu_error, pe220x_ras_peu_error +}; + +static inline unsigned int get_error_num(const struct phytium_edac *edac, + int err_group) +{ + unsigned int error_num = 0; + + error_num = readl(edac->ras_base[err_group] + ERR_DEVID); + + return error_num; +} + +static inline void phytium_ras_setup(const struct phytium_edac *edac) +{ + u64 val = 0; + unsigned int i = 0; + /* + * enable error report and generate interrupt for corrected error event + * first error record owned by node present the node configuration + */ + for (i = 0; i < MAX_ERR_GROUP; i++) { + val = readq(edac->ras_base[i] + ERR_CTLR(0)); + val |= CTLR_ED | CTLR_UI | CTLR_CFI; + writeq(val, edac->ras_base[i] + ERR_CTLR(0)); + } +} + +static ssize_t phytium_edac_inject_ctrl_write(struct file *filp, + const char __user *buf, + size_t size, loff_t *ppos) +{ + int ret = 0; + int res = 0; + unsigned int error_group = 0; + unsigned int error_id = 0; + unsigned int error_num = 0; + struct phytium_edac *edac = filp->private_data; + char str[255]; + char *p_str = str; + char *tmp = NULL; + + if (size > 255) { + ret = -EFAULT; + goto out; + } + + if (copy_from_user(str, buf, size)) { + ret = -EFAULT; + goto out; + } else { + *ppos += size; + ret = size; + } + str[size] = '\0'; + + tmp = strsep(&p_str, ","); + if (!tmp) + goto out; + + res = kstrtouint(tmp, 0, &error_group); + if (res || error_group >= MAX_ERR_GROUP) { + dev_err(edac->dev, "invalid error group parameters"); + goto out; + } + + res = kstrtouint(p_str, 0, &error_id); + if (res) { + dev_err(edac->dev, "invalid error id parameters"); + goto out; + } + + error_num = get_error_num(edac, error_group); + if (error_id >= error_num) { + dev_err(edac->dev, "invalid ras error id.\n"); + goto out; + } + + dev_dbg(edac->dev, "inject group%d, error_id: %d\n", + error_group, error_id); + + if (pe220x_ras_error[error_group][error_id].error_type + == CORRECTED_ERROR) { + writeq(MISC0_CEC(0xFF), + edac->ras_base[error_group] + ERR_MISC0(error_id)); + } + + writel(error_id, edac->ras_base[error_group] + ERR_INJECT); + +out: + return ret; +} + +static const struct file_operations phytium_edac_debug_inject_fops[] = { + { + .open = simple_open, + .write = phytium_edac_inject_ctrl_write, + .llseek = generic_file_llseek, }, + { } +}; + +static void phytium_edac_create_debugfs_nodes(struct phytium_edac *edac) +{ + if (!IS_ENABLED(CONFIG_EDAC_DEBUG) || !edac->dfs) { + dev_info(edac->dev, "edac debug is disable"); + return; + } + + edac_debugfs_create_file("error_inject_ctrl", 0x0200, edac->dfs, edac, + &phytium_edac_debug_inject_fops[0]); +} + +static int phytium_edac_device_add(struct phytium_edac *edac) +{ + struct edac_device_ctl_info *edac_dev; + int res = 0; + + edac_dev = edac_device_alloc_ctl_info( + sizeof(struct edac_device_ctl_info), + "ras", 1, "soc", 1, 0, NULL, + 0, edac_device_alloc_index()); + if (!edac_dev) + res = -ENOMEM; + + edac_dev->dev = edac->dev; + edac_dev->mod_name = EDAC_MOD_STR; + edac_dev->ctl_name = "phytium ras"; + edac_dev->dev_name = "soc"; + + phytium_edac_create_debugfs_nodes(edac); + + res = edac_device_add_device(edac_dev); + if (res > 0) { + dev_err(edac->dev, "edac_device_add_device failed\n"); + goto err_free; + } + + edac->edac_dev = edac_dev; + dev_info(edac->dev, "phytium edac device registered\n"); + return 0; + +err_free: + edac_device_free_ctl_info(edac_dev); + return res; +} + +static int phytium_edac_device_remove(struct phytium_edac *edac) +{ + struct edac_device_ctl_info *edac_dev = edac->edac_dev; + + debugfs_remove_recursive(edac->dfs); + edac_device_del_device(edac_dev->dev); + edac_device_free_ctl_info(edac_dev); + return 0; +} + +static int get_error_id(struct phytium_edac *edac, int *error_id, + int *error_group) +{ + unsigned int error_num = 0; + u64 error_bit = 0; + int ret = 0; + int i = 0; + int err_id = 0; + + /* Iterate over the ras node to check error status */ + for (i = 0; i < MAX_ERR_GROUP; i++) { + error_num = get_error_num(edac, i); + error_bit = readq(edac->ras_base[i] + ERR_GSR); + for (err_id = 0; err_id < error_num; err_id++) { + if (!(error_bit & BIT(err_id))) + continue; + else + break; + } + if (err_id < error_num) { + *error_id = err_id; + *error_group = i; + break; + } + } + + if (i >= MAX_ERR_GROUP) { + ret = -1; + dev_warn(edac->dev, "no error detect.\n"); + } + + return ret; +} + +static void phytium_edac_error_report(struct phytium_edac *edac, + const int error_id, const int error_group) +{ + const struct ras_error_info *err_info = + pe220x_ras_error[error_group]; + + if (err_info[error_id].error_type == UNCORRECTED_ERROR) { + edac_printk(KERN_CRIT, EDAC_MOD_STR, "uncorrected error: %s\n", + err_info[error_id].error_str); + edac_device_handle_ue(edac->edac_dev, 0, 0, + err_info[error_id].error_str); + /* Report the error via the trace interface */ + if (IS_ENABLED(CONFIG_RAS)) + trace_non_standard_event(&NULL_GUID, &NULL_GUID, + EDAC_MOD_STR, SEV_RECOVERABLE, + err_info[error_id].error_str, + strlen(err_info[error_id].error_str)); + } else { + edac_printk(KERN_CRIT, EDAC_MOD_STR, "corrected error: %s\n", + err_info[error_id].error_str); + edac_device_handle_ce(edac->edac_dev, 0, 0, + err_info[error_id].error_str); + if (IS_ENABLED(CONFIG_RAS)) + trace_non_standard_event(&NULL_GUID, &NULL_GUID, + EDAC_MOD_STR, SEV_CORRECTED, + err_info[error_id].error_str, + strlen(err_info[error_id].error_str)); + } +} + +/* + * clear error status and set correct error counter to 0xFE for trigger + * interrupt when next correct error event + */ +static void phytium_edac_clear_error_status(struct phytium_edac *edac, + const int error_id, const int error_group) +{ + writeq(MISC0_CEC(0XFE), edac->ras_base[error_group] + + ERR_MISC0(error_id)); + writeq(GENMASK(31, 0), edac->ras_base[error_group] + + ERR_STATUS(error_id)); +} + +static irqreturn_t phytium_edac_isr(int irq, void *dev_id) +{ + struct phytium_edac *edac = dev_id; + int ret = 0; + int error_group; + int error_id; + + ret = get_error_id(edac, &error_id, &error_group); + if (ret < 0) + goto out; + + phytium_edac_error_report(edac, error_id, error_group); + phytium_edac_clear_error_status(edac, error_id, error_group); + +out: + return IRQ_HANDLED; +} + +static int phytium_edac_probe(struct platform_device *pdev) +{ + struct phytium_edac *edac; + struct resource *res; + int ret = 0; + int irq_cnt = 0; + int irq = 0; + int i = 0; + + edac = devm_kzalloc(&pdev->dev, sizeof(*edac), GFP_KERNEL); + if (!edac) { + ret = -ENOMEM; + goto out; + } + + edac->dev = &pdev->dev; + platform_set_drvdata(pdev, edac); + + edac->ras_base = devm_kcalloc(&pdev->dev, 3, + sizeof(*edac->ras_base), GFP_KERNEL); + if (!edac->ras_base) { + return -ENOMEM; + goto out; + } + + for (i = 0; i < MAX_ERR_GROUP; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + edac->ras_base[i] = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(edac->ras_base[i])) { + dev_err(&pdev->dev, "no resource address\n"); + ret = PTR_ERR(edac->ras_base[i]); + goto out; + } + } + + edac->dfs = edac_debugfs_create_dir(EDAC_MOD_STR); + + ret = phytium_edac_device_add(edac); + if (ret) { + dev_err(&pdev->dev, "can't add edac device"); + goto out; + } + + phytium_ras_setup(edac); + + irq_cnt = platform_irq_count(pdev); + if (irq_cnt < 0) { + dev_err(&pdev->dev, "no irq resource\n"); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < irq_cnt; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + dev_err(&pdev->dev, "invalid irq resource\n"); + ret = -EINVAL; + goto out; + } + ret = devm_request_irq(&pdev->dev, irq, + phytium_edac_isr, IRQF_SHARED, + EDAC_MOD_STR, edac); + if (ret) { + dev_err(&pdev->dev, + "could not request irq %d\n", irq); + goto out; + } + } + +out: + return ret; +} + +static int phytium_edac_remove(struct platform_device *pdev) +{ + struct phytium_edac *edac = dev_get_drvdata(&pdev->dev); + + phytium_edac_device_remove(edac); + + return 0; +} + +static const struct of_device_id phytium_edac_of_match[] = { + { .compatible = "phytium,pe220x-edac" }, + {}, +}; +MODULE_DEVICE_TABLE(of, phytium_edac_of_match); + +static struct platform_driver phytium_edac_driver = { + .probe = phytium_edac_probe, + .remove = phytium_edac_remove, + .driver = { + .name = "phytium-edac", + .of_match_table = phytium_edac_of_match, + }, +}; + +module_platform_driver(phytium_edac_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Huangjie "); -- Gitee From c0e1965da1df9ca90aa20b20d34927629c11b82a Mon Sep 17 00:00:00 2001 From: Lai Xueyu Date: Wed, 2 Aug 2023 17:12:27 +0800 Subject: [PATCH 06/71] mmc: phytium: Fix sdci dma alloc error Dma alloc logic has changed, we need to change the dev_dma_attr for acpi_dma_configure to avoid return NULL. Signed-off-by: Lai Xueyu Signed-off-by: Li Mingzhe Signed-off-by: Wang Yinfeng Change-Id: Ifdc3ada1fe19eb2068bc8d622fe776988e02e38f --- drivers/mmc/host/phytium-sdci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/phytium-sdci.c b/drivers/mmc/host/phytium-sdci.c index ba0296bddda..44379f5589c 100644 --- a/drivers/mmc/host/phytium-sdci.c +++ b/drivers/mmc/host/phytium-sdci.c @@ -1215,7 +1215,7 @@ static int phytium_sdci_probe(struct platform_device *pdev) return -ENODEV; } - acpi_dma_configure(dev, DEV_DMA_NOT_SUPPORTED); + acpi_dma_configure(dev, DEV_DMA_NON_COHERENT); host->clk_rate = 600000000; } else { -- Gitee From 52c5f4c268f35e08e373df8e9b74e65bc36f4df1 Mon Sep 17 00:00:00 2001 From: Lai Xueyu Date: Wed, 27 Dec 2023 10:35:44 +0800 Subject: [PATCH 07/71] mmc: phytium: Bugfix NULL pointer issue in EMMC driver When MCI_INT_MASK_HTO event is triggered and is not a cmd operation, a NULL pointer will be triggered in the "if" judgmemt statement. So we modified the cmd detection logic. Signed-off-by: Lai Xueyu Signed-off-by: Wang Yinfeng Change-Id: Ifafac5bf0b2b6d77047da1f28de03f3896ba4bd9 --- drivers/mmc/host/phytium-mci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/phytium-mci.c b/drivers/mmc/host/phytium-mci.c index 30918bfe6fe..acd5951bf00 100644 --- a/drivers/mmc/host/phytium-mci.c +++ b/drivers/mmc/host/phytium-mci.c @@ -1209,12 +1209,12 @@ static irqreturn_t phytium_mci_irq(int irq, void *dev_id) goto irq_out; } - if ((events & MCI_MASKED_INTS_DTO) && (events & MCI_MASKED_INTS_CMD)) { + if (cmd && (events & MCI_MASKED_INTS_DTO) && (events & MCI_MASKED_INTS_CMD)) { phytium_mci_cmd_done(host, events, mrq, cmd); phytium_mci_data_xfer_done(host, (events & data_ints_mask) | (dmac_events & dmac_ints_mask), mrq, data); - } else if (events & MCI_MASKED_INTS_CMD || - ((events & MCI_INT_MASK_HTO) && (cmd->opcode == SD_SWITCH_VOLTAGE))) { + } else if (cmd && (events & MCI_MASKED_INTS_CMD || + ((events & MCI_INT_MASK_HTO) && (cmd->opcode == SD_SWITCH_VOLTAGE)))) { phytium_mci_cmd_done(host, events, mrq, cmd); } else if (events & MCI_MASKED_INTS_DTO) { phytium_mci_data_xfer_done(host, (events & data_ints_mask) | -- Gitee From edc5effebde558eb2714d808991a2a3d0aa33072 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 9 May 2024 16:46:57 +0800 Subject: [PATCH 08/71] tacho:Phytium: Complement ACPI support for tacho driver This patch used to complement the acpi and set the phytium ACPI ID to PHYT0033. Signed-off-by: Li Yuze Signed-off-by: Wang Yinfeng Signed-off-by: lanhengyu1395 --- drivers/hwmon/tacho-phytium.c | 77 +++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/drivers/hwmon/tacho-phytium.c b/drivers/hwmon/tacho-phytium.c index c89251f3595..00a773014f9 100644 --- a/drivers/hwmon/tacho-phytium.c +++ b/drivers/hwmon/tacho-phytium.c @@ -18,6 +18,7 @@ #include #include #include + #include #define TIMER_CTRL_REG 0x00 @@ -235,24 +236,41 @@ static const struct attribute_group *capture_groups[] = { static int phytium_tacho_get_work_mode(struct phytium_tacho *tacho) { - struct fwnode_handle *nc = dev_fwnode(tacho->dev); + struct device_node *nc = tacho->dev->of_node; + struct fwnode_handle *fwn = tacho->dev->fwnode; - if (fwnode_property_read_bool(nc, "tacho")) + if (of_property_read_bool(nc, "tacho")) + return tacho_mode; + else if (has_acpi_companion(tacho->dev) && fwnode_property_read_bool( + fwn, "tacho")) return tacho_mode; - if (fwnode_property_read_bool(nc, "capture")) + if (of_property_read_bool(nc, "capture")) + return capture_mode; + else if (has_acpi_companion(tacho->dev) && fwnode_property_read_bool( + fwn, "capture")) return capture_mode; return tacho_mode; } static int phytium_tacho_get_edge_mode(struct phytium_tacho *tacho) { - struct fwnode_handle *nc = dev_fwnode(tacho->dev); + struct device_node *nc = tacho->dev->of_node; + struct fwnode_handle *fwn = tacho->dev->fwnode; - if (fwnode_property_read_bool(nc, "up")) + if (of_property_read_bool(nc, "up")) return rising_edge; - if (fwnode_property_read_bool(nc, "down")) + else if (has_acpi_companion(tacho->dev) && fwnode_property_read_bool( + fwn, "up")) + return rising_edge; + if (of_property_read_bool(nc, "down")) + return falling_edge; + else if (has_acpi_companion(tacho->dev) && fwnode_property_read_bool( + fwn, "down")) return falling_edge; - if (fwnode_property_read_bool(nc, "double")) + if (of_property_read_bool(nc, "double")) + return double_edge; + else if (has_acpi_companion(tacho->dev) && fwnode_property_read_bool( + fwn, "double")) return double_edge; return rising_edge; } @@ -260,12 +278,16 @@ static int phytium_tacho_get_edge_mode(struct phytium_tacho *tacho) static int phytium_tacho_get_debounce(struct phytium_tacho *tacho) { u32 value; - struct fwnode_handle *nc = dev_fwnode(tacho->dev); + struct device_node *nc = tacho->dev->of_node; + struct fwnode_handle *fwn = tacho->dev->fwnode; - if (!fwnode_property_read_u32(nc, "debounce-level", &value)) + if (!of_property_read_u32(nc, "debounce-level", &value)) return value; - else - return 0; + if (has_acpi_companion(tacho->dev)) { + if (!fwnode_property_read_u32(fwn, "debounce-level", &value)) + return value; + } + return 0; } static void phytium_tacho_get_of_data(struct phytium_tacho *tacho) @@ -297,19 +319,24 @@ static int phytium_tacho_probe(struct platform_device *pdev) dev_err(&pdev->dev, "region map failed\n"); return PTR_ERR(tacho->base); } - if (dev->of_node) { + + if (!has_acpi_companion(tacho->dev)) { tacho->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(tacho->clk)) return PTR_ERR(tacho->clk); ret = clk_prepare_enable(tacho->clk); if (ret) return ret; - tacho->freq = clk_get_rate(tacho->clk); - } else if (has_acpi_companion(dev)){ - if(fwnode_property_read_u32(dev_fwnode(dev),"clock-frequency", (u32 *)&(tacho->freq) ) <0) - tacho->freq = 50000000; - } + } else { + u32 fre; + + ret = clk_prepare_enable(tacho->clk); + if (ret) + return ret; + fwnode_property_read_u32(tacho->dev->fwnode, "clock-frequency", &fre); + tacho->freq = fre; + } tacho->irq = platform_get_irq(pdev, 0); if (tacho->irq < 0) { @@ -360,27 +387,25 @@ static int phytium_tacho_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(phytium_tacho_pm, phytium_tacho_suspend, phytium_tacho_resume); -#ifdef CONFIG_ACPI -static const struct acpi_device_id phytium_tacho_acpi_ids[] = { - { "PHYT0033", 0 }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(acpi, phytium_tacho_acpi_ids); -#endif - static const struct of_device_id tacho_of_match[] = { { .compatible = "phytium,tacho", }, {}, }; MODULE_DEVICE_TABLE(of, tacho_of_match); +static const struct acpi_device_id tacho_acpi_match[] = { + { "PHYT0033", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, tacho_acpi_match); + static struct platform_driver phytium_tacho_driver = { .probe = phytium_tacho_probe, .driver = { .name = "phytium_tacho", .pm = &phytium_tacho_pm, .of_match_table = of_match_ptr(tacho_of_match), - .acpi_match_table = ACPI_PTR(phytium_tacho_acpi_ids), + .acpi_match_table = ACPI_PTR(tacho_acpi_match), }, }; -- Gitee From f51a62003cb5c093cc4ca6602aa1186654644b2c Mon Sep 17 00:00:00 2001 From: Chen Zhenhua Date: Fri, 8 Mar 2024 09:16:14 +0800 Subject: [PATCH 09/71] pwm: phytium: Add ACPI support for pwm driver This patch used to support acpi and set the phytium ACPI ID to PHYT0029. Signed-off-by: Chen Zhenhua Signed-off-by: Wang Yinfeng Signed-off-by: lanhengyu1395 Change-Id: I1ec84d0bc290d89d0383392f5c8b8bf43a3eac5c --- drivers/pwm/pwm-phytium.c | 110 +++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/pwm/pwm-phytium.c b/drivers/pwm/pwm-phytium.c index 9997ce38ffb..98ae864a82c 100644 --- a/drivers/pwm/pwm-phytium.c +++ b/drivers/pwm/pwm-phytium.c @@ -98,7 +98,6 @@ struct phytium_pwm_chip { struct phytium_pwm_param parameter[MAX_PARAMETER]; unsigned int num_parameters; - unsigned long clk_rate; struct clk *base_clk; }; @@ -185,7 +184,10 @@ static void pwm_phytium_set_periodns(struct pwm_chip *chip, unsigned int periodn int div = our_chip->state.div; u64 cycles; - cycles = our_chip->clk_rate; + if (has_acpi_companion(chip->dev)) + device_property_read_u64(chip->dev, "clock-frequency", &cycles); + else + cycles = clk_get_rate(our_chip->base_clk); cycles *= (periodns / (div + 1)); do_div(cycles, NSEC_PER_SEC); @@ -203,7 +205,10 @@ static void pwm_phytium_set_duty(struct pwm_chip *chip, unsigned int duty, int n int div = our_chip->state.div; u64 cycles; - cycles = our_chip->clk_rate; + if (has_acpi_companion(chip->dev)) + device_property_read_u64(chip->dev, "clock-frequency", &cycles); + else + cycles = clk_get_rate(our_chip->base_clk); cycles *= (duty / (div + 1)); do_div(cycles, NSEC_PER_SEC); @@ -221,7 +226,10 @@ static int pwm_phytium_set_dbcly(struct pwm_chip *chip, unsigned int updbcly, un u64 dbcly, cycles, upcycles, dwcycles; reg = readl(our_chip->base + REG_TPERIOD); - cycles = our_chip->clk_rate; + if (has_acpi_companion(chip->dev)) + device_property_read_u64(chip->dev, "clock-frequency", &cycles); + else + cycles = clk_get_rate(our_chip->base_clk); dbcly &= 0x0; if (updbcly) { upcycles = cycles * updbcly; @@ -399,21 +407,32 @@ static int phytium_pwm_set_parameter(struct phytium_pwm_chip *priv) } static int pwm_phytium_probe_parameter(struct phytium_pwm_chip *priv, - struct fwnode_handle *np) + struct device_node *np) { int nb, ret, array_size; unsigned int i; - array_size = fwnode_property_read_u32_array(np, "phytium,db", NULL, 0); - nb = array_size / (sizeof(struct phytium_pwm_param) / sizeof(u32)); - if (nb <= 0 || nb > MAX_PARAMETER) - return -EINVAL; + if (has_acpi_companion(priv->chip.dev)) { + priv->num_parameters = 1; + array_size = sizeof(struct phytium_pwm_param) / sizeof(u32); + ret = fwnode_property_read_u32_array(dev_fwnode(priv->chip.dev), + "phytium,db", (u32 *)priv->parameter, + array_size); + if (ret < 0) + return ret; + } else { + nb = of_property_count_elems_of_size(np, "phytium,db", + sizeof(struct phytium_pwm_param)); + if (nb <= 0 || nb > MAX_PARAMETER) + return -EINVAL; - priv->num_parameters = nb; - ret = fwnode_property_read_u32_array(np, "phytium,db", - (u32 *)priv->parameter, array_size); - if (ret) - return ret; + priv->num_parameters = nb; + array_size = nb * sizeof(struct phytium_pwm_param) / sizeof(u32); + ret = of_property_read_u32_array(np, "phytium,db", + (u32 *)priv->parameter, array_size); + if (ret) + return ret; + } for (i = 0; i < priv->num_parameters; i++) { if (priv->parameter[i].cntmod > 1 || @@ -428,7 +447,7 @@ static int pwm_phytium_probe_parameter(struct phytium_pwm_chip *priv, static int pwm_phytium_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct fwnode_handle *np = dev_fwnode(dev); + struct device_node *np = dev->of_node; struct phytium_pwm_chip *chip; struct resource *res; int ret; @@ -444,10 +463,11 @@ static int pwm_phytium_probe(struct platform_device *pdev) chip->chip.npwm = PWM_NUM; chip->inverter_mask = BIT(PWM_NUM) - 1; - if (dev->of_node) { + if (pdev->dev.of_node) { chip->chip.of_xlate = of_pwm_xlate_with_flags; chip->chip.of_pwm_n_cells = 3; } + ret = pwm_phytium_probe_parameter(chip, np); if (ret) { dev_err(dev, "failed to set parameter\n"); @@ -458,27 +478,27 @@ static int pwm_phytium_probe(struct platform_device *pdev) chip->base1 = devm_ioremap_resource(&pdev->dev, res); chip->base = (chip->base1 + 0x400); - if (IS_ERR(chip->base)) { - dev_err(dev, "failed to get base_addr\n"); - return PTR_ERR(chip->base); - } - if (dev->of_node) { - chip->base_clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(chip->base_clk)) { - dev_err(dev, "failed to get clk\n"); - return PTR_ERR(chip->base_clk); - } + if (!has_acpi_companion(&pdev->dev)) { + if (IS_ERR(chip->base)) { + dev_err(dev, "failed to get base_addr\n"); + return PTR_ERR(chip->base); + } - ret = clk_prepare_enable(chip->base_clk); - if (ret < 0) { - dev_err(dev, "failed to enable clk\n"); - return ret; - } - chip->clk_rate = clk_get_rate(chip->base_clk); - } else if (has_acpi_companion(dev)){ - if(fwnode_property_read_u32(dev_fwnode(dev),"clock-frequency", (u32 *)&(chip->clk_rate) ) <0) - chip->clk_rate = 50000000; + if (pdev->dev.of_node) { + chip->base_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(chip->base_clk)) { + dev_err(dev, "failed to get clk\n"); + return PTR_ERR(chip->base_clk); + } + + ret = clk_prepare_enable(chip->base_clk); + if (ret < 0) { + dev_err(dev, "failed to enable clk\n"); + return ret; + } + } } + platform_set_drvdata(pdev, chip); ret = pwmchip_add(&chip->chip); @@ -537,26 +557,28 @@ static int pwm_phytium_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(phytium_pwm_dev_pm_ops, pwm_phytium_suspend, pwm_phytium_resume); -#ifdef CONFIG_ACPI -static const struct acpi_device_id phytium_pwm_acpi_ids[] = { - { "PHYT0029", 0 }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(acpi, phytium_pwm_acpi_ids); -#endif - static const struct of_device_id phytium_pwm_matches[] = { { .compatible = "phytium,pwm" }, {}, }; MODULE_DEVICE_TABLE(of, phytium_pwm_matches); +#ifdef CONFIG_ACPI +static const struct acpi_device_id phytium_pwm_acpi_matches[] = { + { "PHYT0029", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, phytium_pwm_acpi_matches); +#endif + static struct platform_driver pwm_phytium_driver = { .driver = { .name = "phytium-pwm", .pm = &phytium_pwm_dev_pm_ops, .of_match_table = phytium_pwm_matches, - .acpi_match_table = ACPI_PTR(phytium_pwm_acpi_ids), +#ifdef CONFIG_ACPI + .acpi_match_table = phytium_pwm_acpi_matches, +#endif }, .probe = pwm_phytium_probe, .remove = pwm_phytium_remove, -- Gitee From 3c1aa75bd7ed2c6af5c25cbe05663987367bad2f Mon Sep 17 00:00:00 2001 From: lanhengyu1395 Date: Fri, 8 Mar 2024 09:22:19 +0800 Subject: [PATCH 10/71] gpio: phytium: Add old gpio-ports index description to adapt old firmware The recently patch for GPIO changed the description of gpio-ports index in gpio-plat drivers, which may cause the driver cannot property read old description in the old ACPI table. Signed-off-by: Lan Hengyu Signed-off-by: Wang Yinfeng Change-Id: Id1fe112be88c0b461d61ce36c9c14322877acbcd --- drivers/gpio/gpio-phytium-platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-phytium-platform.c b/drivers/gpio/gpio-phytium-platform.c index 26a6c75352d..2f808b89e4e 100644 --- a/drivers/gpio/gpio-phytium-platform.c +++ b/drivers/gpio/gpio-phytium-platform.c @@ -78,7 +78,9 @@ static int phytium_gpio_probe(struct platform_device *pdev) } if (fwnode_property_read_u32(fwnode, "ngpios", - &gpio->ngpio[idx])) { + &gpio->ngpio[idx]) + && fwnode_property_read_u32(fwnode, "nr-gpios", + &gpio->ngpio[idx])) { dev_info(dev, "failed to get number of gpios for Port%c\n", idx ? 'B' : 'A'); -- Gitee From 796cc99b500c26cfb68d589b58b2b5c8c899f9b6 Mon Sep 17 00:00:00 2001 From: lanhengyu1395 Date: Fri, 8 Mar 2024 11:24:25 +0800 Subject: [PATCH 11/71] sgpio: phytium: Add ACPI support for SGPIO driver This patch used to support ACPI and set the phytium ACPI ID to PHYT0031 for SGPIO driver. Signed-off-by: Lan Hengyu Signed-off-by: Wang Yinfeng Change-Id: I633eeb8035452ebccee84ea6052ed167af83abdf --- drivers/gpio/gpio-phytium-sgpio.c | 38 +++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-phytium-sgpio.c b/drivers/gpio/gpio-phytium-sgpio.c index 68254af2628..c661a86ae2a 100644 --- a/drivers/gpio/gpio-phytium-sgpio.c +++ b/drivers/gpio/gpio-phytium-sgpio.c @@ -17,6 +17,7 @@ #include #include #include +#include #define SGPIO_CTL0_REG 0x00 #define SGPIO_CTL0_REG_ENABLE BIT(0) @@ -42,6 +43,7 @@ #define SGPIO_RDATA_REG(x) (SGPIO_RDATA0_REG + (x) * 4) #define DEFAULT_L3_L0 0 +#define DEFAULT_CLK 50000000 #define GPIO_GROUP(x) ((x) >> 6) #define GPIO_OFFSET(x) ((x) & GENMASK(5, 0)) @@ -229,17 +231,26 @@ static int phytium_sgpio_probe(struct platform_device *pdev) return -EINVAL; } - gpio->pclk = devm_clk_get(dev, NULL); - if (IS_ERR(gpio->pclk)) { - dev_err(dev, "Could not get the APB clock property\n"); - return PTR_ERR(gpio->pclk); + if (has_acpi_companion(dev)) { + device_property_read_u32(dev, "pclk_freq", &pclk_freq); + if (!pclk_freq || (pclk_freq != 50000000)) { + dev_err(dev, "Could not get APB clock property from acpi, use default clk!\n"); + pclk_freq = DEFAULT_CLK; + } + + } else { + gpio->pclk = devm_clk_get(dev, NULL); + if (IS_ERR(gpio->pclk)) { + dev_err(dev, "Could not get the APB clock property\n"); + return PTR_ERR(gpio->pclk); + } + rc = clk_prepare_enable(gpio->pclk); + if (rc) { + dev_err(dev, "failed to enable pclk: %d\n", rc); + return rc; + } + pclk_freq = clk_get_rate(gpio->pclk); } - rc = clk_prepare_enable(gpio->pclk); - if (rc) { - dev_err(dev, "failed to enable pclk: %d\n", rc); - return rc; - } - pclk_freq = clk_get_rate(gpio->pclk); /* * From the datasheet: @@ -287,10 +298,17 @@ static const struct of_device_id phytium_sgpio_of_match[] = { }; MODULE_DEVICE_TABLE(of, phytium_sgpio_of_match); +static const struct acpi_device_id phytium_sgpio_acpi_match[] = { + { "PHYT0031", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, phytium_sgpio_acpi_match); + static struct platform_driver phytium_sgpio_driver = { .driver = { .name = KBUILD_MODNAME, .of_match_table = of_match_ptr(phytium_sgpio_of_match), + .acpi_match_table = ACPI_PTR(phytium_sgpio_acpi_match), }, .probe = phytium_sgpio_probe, }; -- Gitee From 61d08f5b8a4a5143b8adfd4d0a32d32d974100b2 Mon Sep 17 00:00:00 2001 From: Wang Xu Date: Mon, 11 Mar 2024 11:35:58 +0800 Subject: [PATCH 12/71] hwspinlock: phytium: Add ACPI support for hwspinlock driver This patch add acpi_match_table method and phytium hwspinlock ACPI ID PHYT0053. Signed-off-by: Wang Xu Signed-off-by: Lan Hengyu Signed-off-by: Wang Yinfeng Change-Id: I3ab7cc4f6aafe76c97f7d924950fdc04c43fd788 --- drivers/hwspinlock/phytium_hwspinlock.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/hwspinlock/phytium_hwspinlock.c b/drivers/hwspinlock/phytium_hwspinlock.c index 7958531b0cb..579e6bacc35 100644 --- a/drivers/hwspinlock/phytium_hwspinlock.c +++ b/drivers/hwspinlock/phytium_hwspinlock.c @@ -148,27 +148,27 @@ static int phytium_hwspinlock_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_ACPI -static const struct acpi_device_id phytium_hwspinlock_acpi_ids[] = { - { "PHYT0027", 0 }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(acpi, phytium_hwspinlock_acpi_ids); -#endif - static const struct of_device_id phytium_hwspinlock_of_match[] = { { .compatible = "phytium,hwspinlock", }, { /* end */ }, }; MODULE_DEVICE_TABLE(of, phytium_hwspinlock_of_match); +#ifdef CONFIG_ACPI +static const struct acpi_device_id phytium_hwspinlock_acpi_match[] = { + { "PHYT0053", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, phytium_hwspinlock_acpi_match); +#endif + static struct platform_driver phytium_hwspinlock_driver = { .probe = phytium_hwspinlock_probe, .remove = phytium_hwspinlock_remove, .driver = { .name = "phytium_hwspinlock", .of_match_table = of_match_ptr(phytium_hwspinlock_of_match), - .acpi_match_table = ACPI_PTR(phytium_hwspinlock_acpi_ids), + .acpi_match_table = ACPI_PTR(phytium_hwspinlock_acpi_match), }, }; -- Gitee From a6f5e5915aeea2c2760e9991cdd577f691ba7133 Mon Sep 17 00:00:00 2001 From: Peng Min Date: Mon, 11 Mar 2024 11:40:19 +0800 Subject: [PATCH 13/71] keypad: phytium: Add ACPI support for phytium keypad driver This patch used to support acpi and set phytium ACPI ID to PHYT0028 Signed-off-by: Peng Min Signed-off-by: Lan Hengyu Signed-off-by: Wang Yinfeng Change-Id: I9c6c27e3a21d732674a6c36b6f633cc4bbf59de8 --- drivers/input/keyboard/phytium-keypad.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/input/keyboard/phytium-keypad.c b/drivers/input/keyboard/phytium-keypad.c index c65601bddc5..8237c0051e9 100644 --- a/drivers/input/keyboard/phytium-keypad.c +++ b/drivers/input/keyboard/phytium-keypad.c @@ -394,14 +394,6 @@ static int phytium_keypad_open(struct input_dev *dev) return -EIO; } -#ifdef CONFIG_ACPI -static const struct acpi_device_id phytium_keypad_acpi_ids[] = { - { "PHYT0028", 0 }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(acpi, phytium_keypad_acpi_ids); -#endif - #ifdef CONFIG_OF static const struct of_device_id phytium_keypad_of_match[] = { { .compatible = "phytium,keypad", }, @@ -410,6 +402,14 @@ static const struct of_device_id phytium_keypad_of_match[] = { MODULE_DEVICE_TABLE(of, phytium_keypad_of_match); #endif +#ifdef CONFIG_ACPI +static const struct acpi_device_id phytium_keypad_acpi_match[] = { + { "PHYT0028", 0}, + {} +}; +MODULE_DEVICE_TABLE(acpi, phytium_keypad_acpi_match); +#endif + static int phytium_keypad_probe(struct platform_device *pdev) { const struct matrix_keymap_data *keymap_data = dev_get_platdata(&pdev->dev); @@ -570,7 +570,7 @@ static struct platform_driver phytium_keypad_driver = { .name = "phytium-keypad", .pm = &phytium_keypad_pm_ops, .of_match_table = of_match_ptr(phytium_keypad_of_match), - .acpi_match_table = ACPI_PTR(phytium_keypad_acpi_ids), + .acpi_match_table = ACPI_PTR(phytium_keypad_acpi_match), }, .probe = phytium_keypad_probe, .remove = phytium_keypad_remove, -- Gitee From 01d0080322c46d5a49b2567831e0f471536100c6 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 9 May 2024 17:10:27 +0800 Subject: [PATCH 14/71] hda: phytium: fix typo Signed-off-by: liutianyu1250 --- sound/pci/hda/hda_phytium.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/hda_phytium.c b/sound/pci/hda/hda_phytium.c index b5ed0650e2d..dcf6c18def4 100644 --- a/sound/pci/hda/hda_phytium.c +++ b/sound/pci/hda/hda_phytium.c @@ -655,7 +655,7 @@ static int azx_free(struct azx *chip) } if (bus->irq >= 0) { - free_irq(bus->irq, (void*)chip); + free_irq(bus->irq, (void *)chip); bus->irq = -1; } @@ -925,8 +925,8 @@ static int azx_first_init(struct azx *chip) if (azx_acquire_irq(chip, 0) < 0) return -EBUSY; - strcpy(card->driver, "ft-hda"); - strcpy(card->shortname, "ft-hda"); + strscpy(card->driver, "ft-hda", sizeof(card->driver)); + strscpy(card->shortname, "ft-hda", sizeof(card->shortname)); snprintf(card->longname, sizeof(card->longname), "%s at 0x%lx irq %i", card->shortname, bus->addr, bus->irq); -- Gitee From 17ba884321107126eea5a30be3e46d1b4461fe4e Mon Sep 17 00:00:00 2001 From: Liu Tianyu Date: Mon, 18 Mar 2024 13:48:29 +0800 Subject: [PATCH 15/71] mmc: Phytium-mci: Improve SDIO WIFI RX throughput v2 When SDIO IRQ hanppend, event could be 0x10004, 0x10008, 0x10014 and so on. if we only signal SDIO IRQ only in some speacial case, it may cause SDIO IRQ handle too late. In such SDIO WiFi case, WiFi RX will be too slowly. So we signal all SDIO IRQ to SDIO subsystem. WiFi RX throughput will be improved from 5Mbit/s -> 35Mbit/s. remove #if #endif. Signed-off-by: Liu Tianyu Signed-off-by: Li Mingzhe Signed-off-by: Wang Yinfeng Change-Id: I3756b72513cdcc36e74dd1e063d0ee80a15d7662 --- drivers/mmc/host/phytium-mci.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/phytium-mci.c b/drivers/mmc/host/phytium-mci.c index acd5951bf00..b5e4ee3e9d7 100644 --- a/drivers/mmc/host/phytium-mci.c +++ b/drivers/mmc/host/phytium-mci.c @@ -95,6 +95,7 @@ static void phytium_mci_update_external_clk(struct phytium_mci_host *host, u32 u writel(uhs_reg_value, host->base + MCI_UHS_REG_EXT); while (!(readl(host->base + MCI_CCLK_RDY) & 0x1)) cpu_relax(); + } static void phytium_mci_prepare_data(struct phytium_mci_host *host, @@ -1155,27 +1156,15 @@ static irqreturn_t phytium_mci_irq(int irq, void *dev_id) cmd = host->cmd; data = host->data; -#if 0 - if (((events & event_mask) & MCI_RAW_INTS_SDIO) && - ((events == 0x10001) || (events == 0x10000) || (events == 0x10040))) { - writel(events, host->base + MCI_RAW_INTS); + if ((events & event_mask) & MCI_RAW_INTS_SDIO) __phytium_mci_enable_sdio_irq(host, 0); - sdio_signal_irq(host->mmc); - spin_unlock_irqrestore(&host->lock, flags); - goto irq_out; - } -#endif - if ((events & event_mask) & MCI_RAW_INTS_SDIO) { - __phytium_mci_enable_sdio_irq(host, 0); - } writel((events & event_mask), host->base + MCI_RAW_INTS); writel(dmac_events, host->base + MCI_DMAC_STATUS); spin_unlock_irqrestore(&host->lock, flags); - if ((events & event_mask) & MCI_RAW_INTS_SDIO) { + if ((events & event_mask) & MCI_RAW_INTS_SDIO) sdio_signal_irq(host->mmc); - } if (((events & event_mask) == 0) && ((dmac_evt_mask & dmac_events) == 0)) goto irq_out; -- Gitee From 9c6c34cc2bd72051cd4c8c5cdbbf5a6e74b85eda Mon Sep 17 00:00:00 2001 From: Wang Min Date: Mon, 25 Mar 2024 10:37:37 +0800 Subject: [PATCH 16/71] media: phytium-jpeg: Fix the bug of switching resolution The timer30 and timer31 trigger interrupt threads, should be an atomic operation. There shouldn't be disturbed by other threads during the interval between the two interrupts. Signed-off-by: Wang Min Signed-off-by: Wang Yinfeng Change-Id: I4f4e2673dcc54e45b9ea0e0e046f9a1e04c8f95f --- drivers/media/platform/phytium/phytium_jpeg_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/phytium/phytium_jpeg_core.c b/drivers/media/platform/phytium/phytium_jpeg_core.c index 874f6c5aa5d..014af0162c4 100644 --- a/drivers/media/platform/phytium/phytium_jpeg_core.c +++ b/drivers/media/platform/phytium/phytium_jpeg_core.c @@ -800,6 +800,7 @@ static void phytium_jpeg_resolution_work(struct work_struct *work) if (jpeg_dev->detected_timings.width != jpeg_dev->active_timings.width || jpeg_dev->detected_timings.height != jpeg_dev->active_timings.height || input_status != jpeg_dev->v4l2_input_status) { + static const struct v4l2_event event = { .type = V4L2_EVENT_SOURCE_CHANGE, .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, @@ -899,7 +900,6 @@ static void phytium_jpeg_irq_res_change(struct phytium_jpeg_dev *jpeg_dev, ulong delay) { dev_info(jpeg_dev->dev, "Source resolution is changed, resetting\n"); - set_bit(VIDEO_RES_CHANGE, &jpeg_dev->status); phytium_jpeg_off(jpeg_dev); @@ -1116,6 +1116,7 @@ static irqreturn_t phytium_jpeg_timer30_irq(int irq, void *arg) /* call SE to poweroff JPEG Engine */ arm_smccc_smc(0xc300fff4, 0x9, 0x2, 0x80000020, 0, 0, 0, 0, &res); + set_bit(VIDEO_RES_CHANGE, &jpeg_dev->status); /* set JPEG Engine's status is poweroff */ set_bit(VIDEO_POWEROFF, &jpeg_dev->status); dev_info(jpeg_dev->dev, "timer30 set jpeg status 0x%lx\n", jpeg_dev->status); -- Gitee From f6046e1fbe6b1eb4a6f293c0ba29b28a815695b9 Mon Sep 17 00:00:00 2001 From: Chen Zhenhua Date: Wed, 20 Mar 2024 09:07:28 +0800 Subject: [PATCH 17/71] usb: phytium: Fix the issue of incorrect return value in the hostEp0Irq function. The patch fixes the issue of incorrect return value in the hostEp0Irq function, Sometimes it is necessary to return a value of 1, but always return 0 can cause USB communication error. Signed-off-by: Chen Zhenhua Signed-off-by: Wang Yinfeng Change-Id: I5d1ac26d837c2f9e2fec8bb024e7da6ad2a7d525 --- drivers/usb/phytium/host.c | 131 ++++++++++++++++++++++++++------- drivers/usb/phytium/host_api.h | 3 + 2 files changed, 107 insertions(+), 27 deletions(-) diff --git a/drivers/usb/phytium/host.c b/drivers/usb/phytium/host.c index d58db7afa39..0f86dc23996 100644 --- a/drivers/usb/phytium/host.c +++ b/drivers/usb/phytium/host.c @@ -23,6 +23,71 @@ #define HOST_EP_NUM 16 +static int get_epnum_from_pool(struct HOST_CTRL *priv, int real_epNum, bool dirIn) +{ + int index, dir = 0; + int ret = 0; + + if (!priv) + return 0; + + if (!dirIn) + dir = 1; + + if (real_epNum <= MAX_INSTANCE_EP_NUM) { + if (!priv->ep_remap_pool[dir][real_epNum]) { + priv->ep_remap_pool[dir][real_epNum] = real_epNum; + ret = real_epNum; + goto out; + } + + if (priv->ep_remap_pool[dir][real_epNum] == real_epNum) { + ret = real_epNum; + goto out; + } + } else { + for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) { + if (priv->ep_remap_pool[dir][index] == real_epNum) { + ret = index; + goto out; + } + } + } + + for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) { + if (!priv->ep_remap_pool[dir][index]) { + priv->ep_remap_pool[dir][index] = real_epNum; + ret = index; + goto out; + } + } + +out: + return ret; +} + +static int release_epnum_from_pool(struct HOST_CTRL *priv, int real_epNum, bool dirIn) +{ + int index = 0; + int dir = 0; + + if (!priv) + return 0; + + if (!dirIn) + dir = 1; + + for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) { + if (priv->ep_remap_pool[dir][index] == real_epNum) { + priv->ep_remap_pool[dir][index] = 0; + + return 0; + } + } + + return 0; +} + static inline struct HOST_REQ *getUsbRequestEntry(struct list_head *list) { return (struct HOST_REQ *)((uintptr_t)list - (uintptr_t)&(((struct HOST_REQ *)0)->list)); @@ -85,6 +150,7 @@ static inline void disconnectHostDetect(struct HOST_CTRL *priv) if (!priv) return; + memset(priv->ep_remap_pool, 0, sizeof(priv->ep_remap_pool)); otgctrl = phytium_read8(&priv->regs->otgctrl); if ((otgctrl & OTGCTRL_ASETBHNPEN) && priv->otgState == HOST_OTG_STATE_A_SUSPEND) pr_info("Device no Response\n"); @@ -571,7 +637,7 @@ static void hostEpProgram(struct HOST_CTRL *priv, struct HostEp *hwEp, phytium_write8(&priv->regs->ep[hwEp->hwEpNum - 1].txcon, regCon); if (usbEpPriv->type != USB_ENDPOINT_XFER_ISOC) { retval = priv->hostCallbacks.getEpToggle(priv, - usbReq->usbDev, usbEpPriv->epNum, 0); + usbReq->usbDev, usbHEp->device_epNum, 0); if (retval) { phytium_write8(&priv->regs->endprst, hwEp->hwEpNum | ENDPRST_IO_TX); @@ -592,7 +658,7 @@ static void hostEpProgram(struct HOST_CTRL *priv, struct HostEp *hwEp, usbEpPriv->maxPacketSize); phytium_write8(&priv->regs->epExt[hwEp->hwEpNum - 1].txctrl, - usbEpPriv->epNum); + usbHEp->device_epNum); phytium_write8(&priv->regs->fnaddr, usbEpPriv->faddress); @@ -629,7 +695,7 @@ static void hostEpProgram(struct HOST_CTRL *priv, struct HostEp *hwEp, if (usbEpPriv->type != USB_ENDPOINT_XFER_ISOC) { if (priv->hostCallbacks.getEpToggle) { retval = priv->hostCallbacks.getEpToggle(priv, - usbReq->usbDev, usbEpPriv->epNum, 1); + usbReq->usbDev, usbHEp->device_epNum, 1); if (retval) { phytium_write8(&priv->regs->endprst, hwEp->hwEpNum); phytium_write8(&priv->regs->endprst, hwEp->hwEpNum | @@ -646,7 +712,7 @@ static void hostEpProgram(struct HOST_CTRL *priv, struct HostEp *hwEp, usbEpPriv->maxPacketSize); phytium_write8(&priv->regs->epExt[hwEp->hwEpNum - 1].rxctrl, - usbEpPriv->epNum); + usbHEp->device_epNum); phytium_write8(&priv->regs->fnaddr, usbEpPriv->faddress); @@ -837,7 +903,7 @@ static void scheduleNextTransfer(struct HOST_CTRL *priv, endprst = (phytium_read8(&priv->regs->endprst) & ENDPRST_TOGSETQ) ? 1 : 0; if (priv->hostCallbacks.setEpToggle) priv->hostCallbacks.setEpToggle(priv, usbReq->usbDev, - usbHEpPriv->epNum, usbHEpPriv->isIn, endprst); + usbEp->device_epNum, usbHEpPriv->isIn, endprst); } else { if (waitForBusyBit(priv, hwEp) > 0) { usbReq->status = HOST_ESHUTDOWN; @@ -849,7 +915,7 @@ static void scheduleNextTransfer(struct HOST_CTRL *priv, endprst = (phytium_read8(&priv->regs->endprst) & ENDPRST_TOGSETQ) ? 1 : 0; if (priv->hostCallbacks.setEpToggle) priv->hostCallbacks.setEpToggle(priv, usbReq->usbDev, - usbHEpPriv->epNum, usbHEpPriv->isIn, endprst); + usbEp->device_epNum, usbHEpPriv->isIn, endprst); } break; } @@ -995,7 +1061,7 @@ static int32_t hostEp0Irq(struct HOST_CTRL *priv, uint8_t isIn) scheduleNextTransfer(priv, usbReq, hwEp); } - return 0; + return ret; } static void updateTimeIntTransfer(struct list_head *head, struct HOST_EP_PRIV *lastFinished) @@ -1169,9 +1235,8 @@ static void host_endpoint_update(struct phytium_cusb *config, if (!config || !udev || !ep) return; - epnum = usb_endpoint_num(&ep->desc); - if (epnum > MAX_INSTANCE_EP_NUM) - epnum = MAX_INSTANCE_EP_NUM; + epnum = get_epnum_from_pool(config->host_priv, usb_endpoint_num(&ep->desc), + usb_endpoint_dir_in(&ep->desc)); if (usb_endpoint_dir_out(&ep->desc)) { if (udev->out_ep[epnum] == NULL) { @@ -1243,9 +1308,8 @@ static int hc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) req->isoFramesDesc = NULL; req->isoFramesNumber = urb->number_of_packets; - req->epNum = usb_endpoint_num(host_ep_desc); - if (req->epNum > MAX_INSTANCE_EP_NUM) - req->epNum = MAX_INSTANCE_EP_NUM; + req->epNum = get_epnum_from_pool(config->host_priv, usb_endpoint_num(host_ep_desc), + usb_endpoint_dir_in(host_ep_desc)); if (usb_endpoint_dir_in(host_ep_desc)) { if (!usbDev->in_ep[req->epNum]) @@ -1280,6 +1344,7 @@ static int hc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) req->status = EINPROGRESS; req->usbDev = &usbDev->udev; req->usbEp = req->epIsIn ? usbDev->in_ep[req->epNum] : usbDev->out_ep[req->epNum]; + req->usbEp->device_epNum = usb_endpoint_num(host_ep_desc); if (!req->epNum) usbDev->ep0_hep.desc.wMaxPacketSize = urb->dev->ep0.desc.wMaxPacketSize; @@ -1321,6 +1386,10 @@ static int hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto err_giveback; ret = config->host_obj->host_reqDequeue(priv, urb->hcpriv, status); + + release_epnum_from_pool(config->host_priv, usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe)); + kfree(urb->hcpriv); urb->hcpriv = NULL; done: @@ -1338,10 +1407,15 @@ static int hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) static void hc_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ld_ep) { struct HOST_USB_DEVICE *usbDev; - int ep_num = usb_endpoint_num(&ld_ep->desc); + int ep_num; + struct phytium_cusb *config; - if (ep_num > MAX_INSTANCE_EP_NUM) - ep_num = MAX_INSTANCE_EP_NUM; + config = *(struct phytium_cusb **)hcd->hcd_priv; + if (!config) + return; + + ep_num = get_epnum_from_pool(config->host_priv, usb_endpoint_num(&ld_ep->desc), + usb_endpoint_dir_in(&ld_ep->desc)); usbDev = (struct HOST_USB_DEVICE *)ld_ep->hcpriv; if (!usbDev) @@ -1349,14 +1423,14 @@ static void hc_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *l if (ld_ep->desc.bEndpointAddress) { if (usb_endpoint_dir_in(&ld_ep->desc)) { - if (!usbDev->in_ep[ep_num]) { + if (usbDev->in_ep[ep_num]) { usbDev->in_ep[ep_num]->userExt = NULL; INIT_LIST_HEAD(&usbDev->in_ep[ep_num]->reqList); kfree(usbDev->in_ep[ep_num]); usbDev->in_ep[ep_num] = NULL; } } else { - if (!usbDev->out_ep[ep_num]) { + if (usbDev->out_ep[ep_num]) { usbDev->out_ep[ep_num]->userExt = NULL; INIT_LIST_HEAD(&usbDev->out_ep[ep_num]->reqList); kfree(usbDev->out_ep[ep_num]); @@ -1699,6 +1773,7 @@ static uint32_t initEndpoints(struct HOST_CTRL *priv) priv->hwEpOutCount = 0; phytium_write8(&priv->regs->ep0fifoctrl, FIFOCTRL_FIFOAUTO | 0); phytium_write8(&priv->regs->ep0fifoctrl, FIFOCTRL_FIFOAUTO | FIFOCTRL_IO_TX | 0); + memset(priv->ep_remap_pool, 0, sizeof(priv->ep_remap_pool)); for (epNum = 0; epNum < HOST_EP_NUM; epNum++) { priv->in[epNum].isInEp = 1; @@ -1949,7 +2024,8 @@ int32_t hostEpDisable(struct HOST_CTRL *priv, struct HOST_EP *ep) return 0; } -unsigned int get_endpoint_interval(struct usb_endpoint_descriptor desc, int speed) +unsigned int get_endpoint_interval(struct usb_endpoint_descriptor desc, + int speed) { unsigned int interval = 0; @@ -1961,9 +2037,9 @@ unsigned int get_endpoint_interval(struct usb_endpoint_descriptor desc, int spee interval = fls(desc.bInterval) - 1; interval = clamp_val(interval, 0, 15); interval = 1 << interval; - if (interval != desc.bInterval) + if ((1 << interval) != desc.bInterval) pr_debug("rounding to %d microframes, desc %d microframes\n", - interval, desc.bInterval); + 1 << interval, desc.bInterval); break; } @@ -1971,16 +2047,17 @@ unsigned int get_endpoint_interval(struct usb_endpoint_descriptor desc, int spee interval = clamp_val(desc.bInterval, 1, 16) - 1; interval = 1 << interval; if (interval != desc.bInterval - 1) - pr_debug("rounding to %d %sframes\n", interval, - speed == USB_SPEED_FULL ? "" : "micro"); + pr_debug("rounding to %d %sframes\n", 1 << interval, + speed == USB_SPEED_FULL ? "" : "micro"); } break; case USB_SPEED_FULL: if (usb_endpoint_xfer_isoc(&desc)) { - interval = clamp_val(desc.bInterval, 1, 16); - if (interval != desc.bInterval) + interval = clamp_val(desc.bInterval, 1, 16) - 1; + if (interval != desc.bInterval - 1) pr_debug("rounding to %d %sframes\n", 1 << interval, - speed == USB_SPEED_FULL ? "" : "micro"); + speed == USB_SPEED_FULL ? "" : "micro"); + interval += 3; break; } fallthrough; @@ -1990,7 +2067,7 @@ unsigned int get_endpoint_interval(struct usb_endpoint_descriptor desc, int spee interval = clamp_val(interval, 3, 10); if ((1 << interval) != desc.bInterval * 8) pr_debug("rounding to %d microframes, desc %d microframes\n", - 1 << interval, desc.bInterval); + 1 << interval, desc.bInterval); } } diff --git a/drivers/usb/phytium/host_api.h b/drivers/usb/phytium/host_api.h index 3d45258278c..b99d2b4980f 100644 --- a/drivers/usb/phytium/host_api.h +++ b/drivers/usb/phytium/host_api.h @@ -10,6 +10,7 @@ #define MAX_SUPPORTED_DEVICES 16 #define USB_PORT_STAT_RESUME (1 << 31) #define MAX_INSTANCE_EP_NUM 6 +#define ENDPOINT_DIR 2 enum HOST_OtgState { HOST_OTG_STATE_A_IDLE, @@ -63,6 +64,7 @@ struct HOST_EP { struct list_head reqList; void *userExt; uint8_t *hcPriv; + uint8_t device_epNum; }; struct HOST_USB_DEVICE { @@ -241,6 +243,7 @@ struct HOST_CTRL { struct HOST_USB_DEVICE *host_devices_table[MAX_SUPPORTED_DEVICES]; struct CUSTOM_REGS *custom_regs; struct VHUB_REGS *vhub_regs; + int ep_remap_pool[ENDPOINT_DIR][MAX_INSTANCE_EP_NUM + 1]; }; struct HOST_OBJ *HOST_GetInstance(void); -- Gitee From c2cc453f7acbe961747690be3a0aee898d178991 Mon Sep 17 00:00:00 2001 From: Li Wencheng Date: Mon, 25 Mar 2024 14:08:37 +0800 Subject: [PATCH 18/71] net: phy: Bugfix rmmod phylink module fail problem The phylink driver module must have an exit function to exit. If not, it cannot exit. Signed-off-by: Li Wencheng Signed-off-by: Wang Yinfeng Change-Id: Idb465b33a35b167ca0dedadde4deae80caf5abba --- drivers/net/phy/phylink.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index b5f012619e4..fead848224b 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -3739,6 +3739,11 @@ static int __init phylink_init(void) return 0; } +static void __exit phylink_exit(void) +{ +} + module_init(phylink_init); +module_exit(phylink_exit); MODULE_LICENSE("GPL v2"); -- Gitee From 78f7b2da845a32c8b6eec25fdc04f280812dd486 Mon Sep 17 00:00:00 2001 From: Song Wenting Date: Mon, 25 Mar 2024 14:23:13 +0800 Subject: [PATCH 19/71] dt-bindings: macb: Add bindings for Phytium gem1.0 and gem 2.0 This patch document the DT bindings for the Phytium gem1.0 and gem2.0 controller. Signed-off-by: Song Wenting Signed-off-by: Li Wencheng Signed-off-by: Wang Yinfeng Change-Id: If47ffcb9c93b84a8e469149994c8f616d0822058 --- Documentation/devicetree/bindings/net/cdns,macb.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/net/cdns,macb.yaml b/Documentation/devicetree/bindings/net/cdns,macb.yaml index c09fcf5041c..1eaddca0219 100644 --- a/Documentation/devicetree/bindings/net/cdns,macb.yaml +++ b/Documentation/devicetree/bindings/net/cdns,macb.yaml @@ -63,6 +63,8 @@ properties: - cdns,emac # Generic - cdns,gem # Generic - cdns,macb # Generic + - cdns,phytium-gem-1.0 # GEM version 1.0 on Phytium SoCs + - cdns,phytium-gem-2.0 # GEM version 2.0 on Phytium SoCs reg: minItems: 1 -- Gitee From 9e3dd2fd6d3ce3b86ca32fb0d1cadcda6effdfee Mon Sep 17 00:00:00 2001 From: Song Wenting Date: Mon, 25 Mar 2024 14:28:29 +0800 Subject: [PATCH 20/71] net: macb: Add support for Phytium gem1.0 and gem 2.0 This patch modify macb driver to support the Phytium gem1.0 and gem2.0 controller. Signed-off-by: Song Wenting Signed-off-by: Li Wencheng Signed-off-by: Wang Yinfeng Change-Id: Ief96dd0af4b0be233dd90574823785a38bf52410 --- drivers/net/ethernet/cadence/macb.h | 85 ++- drivers/net/ethernet/cadence/macb_main.c | 895 ++++++++++++++--------- 2 files changed, 593 insertions(+), 387 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 44bf7a98225..3a5441dcc73 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -85,7 +85,7 @@ #define GEM_PBUFRXCUT 0x0044 /* RX Partial Store and Forward */ #define GEM_JML 0x0048 /* Jumbo Max Length */ #define GEM_HS_MAC_CONFIG 0x0050 /* GEM high speed config */ -#define GEM_AXI_PIPE 0x0054 /* AXI max pipeline register*/ +#define GEM_AXI_PIPE 0x0054 /* Axi max pipeline register*/ #define GEM_HRB 0x0080 /* Hash Bottom */ #define GEM_HRT 0x0084 /* Hash Top */ #define GEM_SA1B 0x0088 /* Specific1 Bottom */ @@ -186,7 +186,6 @@ #define GEM_DCFG12 0x02AC /* Design Config 12 */ #define GEM_USX_CONTROL 0x0A80 /* High speed PCS control register */ #define GEM_USX_STATUS 0x0A88 /* High speed PCS status register */ -#define GEM_TAIL_ENABLE 0x0E7C /* Phytium: Enable tail */ #define GEM_TXBDCTRL 0x04cc /* TX Buffer Descriptor control register */ #define GEM_RXBDCTRL 0x04d0 /* RX Buffer Descriptor control register */ @@ -221,31 +220,36 @@ #define GEM_IER(hw_q) (0x0600 + ((hw_q) << 2)) #define GEM_IDR(hw_q) (0x0620 + ((hw_q) << 2)) #define GEM_IMR(hw_q) (0x0640 + ((hw_q) << 2)) -#define GEM_TAIL(hw_q) (0x0e80 + ((hw_q) << 2)) /* Phytium: tail register */ -#define GEM_SRC_SEL_LN 0x1C04 -#define GEM_DIV_SEL0_LN 0x1C08 -#define GEM_DIV_SEL1_LN 0x1C0C + +#define GEM_SRC_SEL_LN 0x1C04 +#define GEM_DIV_SEL0_LN 0x1C08 +#define GEM_DIV_SEL1_LN 0x1C0C #define GEM_PMA_XCVR_POWER_STATE 0x1C10 -#define GEM_SPEED_MODE 0x1C14 -#define GEM_MII_SELECT 0x1C18 -#define GEM_SEL_MII_ON_RGMII 0x1C1C -#define GEM_TX_CLK_SEL0 0x1C20 -#define GEM_TX_CLK_SEL1 0x1C24 -#define GEM_TX_CLK_SEL2 0x1C28 -#define GEM_TX_CLK_SEL3 0x1C2C -#define GEM_RX_CLK_SEL0 0x1C30 -#define GEM_RX_CLK_SEL1 0x1C34 +#define GEM_SPEED_MODE 0x1C14 +#define GEM_MII_SELECT 0x1C18 +#define GEM_SEL_MII_ON_RGMII 0x1C1C +#define GEM_TX_CLK_SEL0 0x1C20 +#define GEM_TX_CLK_SEL1 0x1C24 +#define GEM_TX_CLK_SEL2 0x1C28 +#define GEM_TX_CLK_SEL3 0x1C2C +#define GEM_RX_CLK_SEL0 0x1C30 +#define GEM_RX_CLK_SEL1 0x1C34 #define GEM_CLK_250M_DIV10_DIV100_SEL 0x1C38 -#define GEM_TX_CLK_SEL5 0x1C3C -#define GEM_TX_CLK_SEL6 0x1C40 -#define GEM_RX_CLK_SEL4 0x1C44 -#define GEM_RX_CLK_SEL5 0x1C48 -#define GEM_TX_CLK_SEL3_0 0x1C70 -#define GEM_TX_CLK_SEL4_0 0x1C74 -#define GEM_RX_CLK_SEL3_0 0x1C78 -#define GEM_RX_CLK_SEL4_0 0x1C7C -#define GEM_RGMII_TX_CLK_SEL0 0x1C80 -#define GEM_RGMII_TX_CLK_SEL1 0x1C84 +#define GEM_TX_CLK_SEL5 0x1C3C +#define GEM_TX_CLK_SEL6 0x1C40 +#define GEM_RX_CLK_SEL4 0x1C44 +#define GEM_RX_CLK_SEL5 0x1C48 +#define GEM_TX_CLK_SEL3_0 0x1C70 +#define GEM_TX_CLK_SEL4_0 0x1C74 +#define GEM_RX_CLK_SEL3_0 0x1C78 +#define GEM_RX_CLK_SEL4_0 0x1C7C +#define GEM_RGMII_TX_CLK_SEL0 0x1C80 +#define GEM_RGMII_TX_CLK_SEL1 0x1C84 + +#define GEM_PHY_INT_ENABLE 0x1C88 +#define GEM_PHY_INT_CLEAR 0x1C8C +#define GEM_PHY_INT_STATE 0x1C90 +#define GEM_INTX_IRQ_MASK 0x1C7C /* Phytium: irq mask */ /* Bitfields in NCR */ #define MACB_LB_OFFSET 0 /* reserved */ @@ -762,8 +766,10 @@ #define MACB_CAPS_GEM_HAS_PTP 0x00000040 #define MACB_CAPS_BD_RD_PREFETCH 0x00000080 #define MACB_CAPS_NEEDS_RSTONUBR 0x00000100 +#define MACB_CAPS_SEL_CLK 0x00000800 #define MACB_CAPS_MIIONRGMII 0x00000200 #define MACB_CAPS_NEED_TSUCLK 0x00000400 +#define MACB_CAPS_SEL_CLK 0x00000800 #define MACB_CAPS_PCS 0x01000000 #define MACB_CAPS_HIGH_SPEED 0x02000000 #define MACB_CAPS_CLK_HW_CHG 0x04000000 @@ -772,9 +778,8 @@ #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 #define MACB_CAPS_SG_DISABLED 0x40000000 #define MACB_CAPS_MACB_IS_GEM 0x80000000 -#define MACB_CAPS_SEL_CLK_HW 0x00001000 -#define MACB_CAPS_SEL_CLK_HW_2 0x00002000 -#define MACB_CAPS_TAILPTR 0x00004000 /* Phytium: tail register */ +#define MACB_CAPS_PCS 0x01000000 +#define MACB_CAPS_HIGH_SPEED 0x02000000 /* LSO settings */ #define MACB_LSO_UFO_ENABLE 0x01 @@ -817,6 +822,8 @@ #define gem_readl_n(port, reg, idx) (port)->macb_reg_readl((port), GEM_##reg + idx * 4) #define gem_writel_n(port, reg, idx, value) (port)->macb_reg_writel((port), GEM_##reg + idx * 4, (value)) +#define PTP_TS_BUFFER_SIZE 128 /* must be power of 2 */ + /* Conditional GEM/MACB macros. These perform the operation to the correct * register dependent on whether the device is a GEM or a MACB. For registers * and bitfields that are common across both devices, use macb_{read,write}l @@ -866,6 +873,11 @@ struct macb_dma_desc_ptp { u32 ts_1; u32 ts_2; }; + +struct gem_tx_ts { + struct sk_buff *skb; + struct macb_dma_desc_ptp desc_ptp; +}; #endif /* DMA descriptor bitfields */ @@ -1227,6 +1239,7 @@ struct macb_config { unsigned int max_tx_length; int jumbo_max_len; const struct macb_usrio_config *usrio; + void (*sel_clk_hw)(struct macb *bp, int speed); }; struct tsu_incr { @@ -1247,7 +1260,7 @@ struct macb_queue { unsigned int RBQS; unsigned int RBQP; unsigned int RBQPH; - unsigned int TAILADDR; + /* Lock to protect tx_head and tx_tail */ spinlock_t tx_ptr_lock; unsigned int tx_head, tx_tail; @@ -1265,8 +1278,15 @@ struct macb_queue { struct macb_dma_desc *rx_ring; struct sk_buff **rx_skbuff; void *rx_buffers; + struct napi_struct napi; struct napi_struct napi_rx; struct queue_stats stats; + +#ifdef CONFIG_MACB_USE_HWSTAMP + struct work_struct tx_ts_task; + unsigned int tx_ts_head, tx_ts_tail; + struct gem_tx_ts tx_timestamps[PTP_TS_BUFFER_SIZE]; +#endif }; struct ethtool_rx_fs_item { @@ -1304,6 +1324,7 @@ struct macb { struct clk *rx_clk; struct clk *tsu_clk; struct net_device *dev; + struct ncsi_dev *ndev; union { struct macb_stats macb; struct gem_stats gem; @@ -1316,7 +1337,9 @@ struct macb { struct phylink_config phylink_config; struct phylink_pcs phylink_usx_pcs; struct phylink_pcs phylink_sgmii_pcs; - struct ncsi_dev *ndev; + int link; + int speed; + int duplex; int use_ncsi; u32 caps; @@ -1366,6 +1389,8 @@ struct macb { struct macb_pm_data pm_data; const struct macb_usrio_config *usrio; + + void (*sel_clk_hw)(struct macb *bp, int speed); }; #ifdef CONFIG_MACB_USE_HWSTAMP diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 4c7fbd437fa..a836921fb0b 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -6,7 +6,6 @@ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include @@ -27,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "macb.h" @@ -49,6 +50,9 @@ struct sifive_fu540_macb_mgmt { struct clk_hw hw; }; +#define MAX_RING_ADDR_ALLOC_TIMES 3 +#define RING_ADDR_INTERVAL 128 + #define MACB_RX_BUFFER_SIZE 128 #define RX_BUFFER_MULTIPLE 64 /* bytes */ @@ -89,12 +93,12 @@ struct sifive_fu540_macb_mgmt { #define MACB_WOL_HAS_MAGIC_PACKET (0x1 << 0) #define MACB_WOL_ENABLED (0x1 << 1) -#define HS_SPEED_100M 0 -#define HS_SPEED_1000M 1 -#define HS_SPEED_2500M 2 -#define HS_SPEED_5000M 3 -#define HS_SPEED_10000M 4 -#define MACB_SERDES_RATE_5G 0 +#define HS_SPEED_100M 0 +#define HS_SPEED_1000M 1 +#define HS_SPEED_2500M 2 +#define HS_SPEED_5000M 3 +#define HS_SPEED_10000M 4 +#define MACB_SERDES_RATE_5G 0 #define MACB_SERDES_RATE_10G 1 /* Graceful stop timeouts in us. We should allow up to @@ -105,6 +109,10 @@ struct sifive_fu540_macb_mgmt { #define MACB_MDIO_TIMEOUT 1000000 /* in usecs */ +static void macb_tx_unmap(struct macb *bp, + struct macb_tx_skb *tx_skb, + int budget); + /* DMA buffer descriptor might be different size * depends on hardware configuration: * @@ -569,162 +577,7 @@ static void macb_set_tx_clk(struct macb *bp, int speed) netdev_err(bp->dev, "adjusting tx_clk failed.\n"); } -static int phytium_gem_sel_clk(struct macb *bp, int spd) -{ - int speed = 0; - - if (bp->phy_interface == PHY_INTERFACE_MODE_USXGMII || - bp->phy_interface == PHY_INTERFACE_MODE_10GBASER) { - gem_writel(bp, SRC_SEL_LN, 0x1); - if (spd == SPEED_5000) { - gem_writel(bp, DIV_SEL0_LN, 0x8); - gem_writel(bp, DIV_SEL1_LN, 0x2); - gem_writel(bp, PMA_XCVR_POWER_STATE, 0x0); - speed = HS_SPEED_5000M; - } else { - gem_writel(bp, DIV_SEL0_LN, 0x4); - gem_writel(bp, DIV_SEL1_LN, 0x1); - gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); - speed = HS_SPEED_10000M; - } - } else if (bp->phy_interface == PHY_INTERFACE_MODE_5GBASER) { - gem_writel(bp, SRC_SEL_LN, 0x1); - gem_writel(bp, DIV_SEL0_LN, 0x8); - gem_writel(bp, DIV_SEL1_LN, 0x2); - gem_writel(bp, PMA_XCVR_POWER_STATE, 0x0); - speed = HS_SPEED_5000M; - } else if (bp->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { - gem_writel(bp, SRC_SEL_LN, 0x1); - gem_writel(bp, DIV_SEL0_LN, 0x1); - gem_writel(bp, DIV_SEL1_LN, 0x2); - gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); - gem_writel(bp, TX_CLK_SEL0, 0x0); - gem_writel(bp, TX_CLK_SEL1, 0x1); - gem_writel(bp, TX_CLK_SEL2, 0x1); - gem_writel(bp, TX_CLK_SEL3, 0x1); - gem_writel(bp, RX_CLK_SEL0, 0x1); - gem_writel(bp, RX_CLK_SEL1, 0x0); - gem_writel(bp, TX_CLK_SEL3_0, 0x0); - gem_writel(bp, TX_CLK_SEL4_0, 0x0); - gem_writel(bp, RX_CLK_SEL3_0, 0x0); - gem_writel(bp, RX_CLK_SEL4_0, 0x0); - speed = HS_SPEED_2500M; - } else if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { - if (spd == SPEED_1000) { - gem_writel(bp, SRC_SEL_LN, 0x1); - gem_writel(bp, DIV_SEL0_LN, 0x4); - gem_writel(bp, DIV_SEL1_LN, 0x8); - gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); - gem_writel(bp, TX_CLK_SEL0, 0x0); - gem_writel(bp, TX_CLK_SEL1, 0x0); - gem_writel(bp, TX_CLK_SEL2, 0x0); - gem_writel(bp, TX_CLK_SEL3, 0x1); - gem_writel(bp, RX_CLK_SEL0, 0x1); - gem_writel(bp, RX_CLK_SEL1, 0x0); - gem_writel(bp, TX_CLK_SEL3_0, 0x0); - gem_writel(bp, TX_CLK_SEL4_0, 0x0); - gem_writel(bp, RX_CLK_SEL3_0, 0x0); - gem_writel(bp, RX_CLK_SEL4_0, 0x0); - speed = HS_SPEED_1000M; - } else if (spd == SPEED_100 || spd == SPEED_10) { - gem_writel(bp, SRC_SEL_LN, 0x1); - gem_writel(bp, DIV_SEL0_LN, 0x4); - gem_writel(bp, DIV_SEL1_LN, 0x8); - gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); - gem_writel(bp, TX_CLK_SEL0, 0x0); - gem_writel(bp, TX_CLK_SEL1, 0x0); - gem_writel(bp, TX_CLK_SEL2, 0x1); - gem_writel(bp, TX_CLK_SEL3, 0x1); - gem_writel(bp, RX_CLK_SEL0, 0x1); - gem_writel(bp, RX_CLK_SEL1, 0x0); - gem_writel(bp, TX_CLK_SEL3_0, 0x1); - gem_writel(bp, TX_CLK_SEL4_0, 0x0); - gem_writel(bp, RX_CLK_SEL3_0, 0x0); - gem_writel(bp, RX_CLK_SEL4_0, 0x1); - speed = HS_SPEED_100M; - } - } else if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII || - bp->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) { - if (spd == SPEED_1000) { - gem_writel(bp, MII_SELECT, 0x1); - gem_writel(bp, SEL_MII_ON_RGMII, 0x0); - gem_writel(bp, TX_CLK_SEL0, 0x0); - gem_writel(bp, TX_CLK_SEL1, 0x1); - gem_writel(bp, TX_CLK_SEL2, 0x0); - gem_writel(bp, TX_CLK_SEL3, 0x0); - gem_writel(bp, RX_CLK_SEL0, 0x0); - gem_writel(bp, RX_CLK_SEL1, 0x1); - gem_writel(bp, CLK_250M_DIV10_DIV100_SEL, 0x0); - gem_writel(bp, RX_CLK_SEL5, 0x1); - gem_writel(bp, RGMII_TX_CLK_SEL0, 0x1); - gem_writel(bp, RGMII_TX_CLK_SEL1, 0x0); - speed = HS_SPEED_1000M; - } else if (spd == SPEED_100) { - gem_writel(bp, MII_SELECT, 0x1); - gem_writel(bp, SEL_MII_ON_RGMII, 0x0); - gem_writel(bp, TX_CLK_SEL0, 0x0); - gem_writel(bp, TX_CLK_SEL1, 0x1); - gem_writel(bp, TX_CLK_SEL2, 0x0); - gem_writel(bp, TX_CLK_SEL3, 0x0); - gem_writel(bp, RX_CLK_SEL0, 0x0); - gem_writel(bp, RX_CLK_SEL1, 0x1); - gem_writel(bp, CLK_250M_DIV10_DIV100_SEL, 0x0); - gem_writel(bp, RX_CLK_SEL5, 0x1); - gem_writel(bp, RGMII_TX_CLK_SEL0, 0x0); - gem_writel(bp, RGMII_TX_CLK_SEL1, 0x0); - speed = HS_SPEED_100M; - } else { - gem_writel(bp, MII_SELECT, 0x1); - gem_writel(bp, SEL_MII_ON_RGMII, 0x0); - gem_writel(bp, TX_CLK_SEL0, 0x0); - gem_writel(bp, TX_CLK_SEL1, 0x1); - gem_writel(bp, TX_CLK_SEL2, 0x0); - gem_writel(bp, TX_CLK_SEL3, 0x0); - gem_writel(bp, RX_CLK_SEL0, 0x0); - gem_writel(bp, RX_CLK_SEL1, 0x1); - gem_writel(bp, CLK_250M_DIV10_DIV100_SEL, 0x1); - gem_writel(bp, RX_CLK_SEL5, 0x1); - gem_writel(bp, RGMII_TX_CLK_SEL0, 0x0); - gem_writel(bp, RGMII_TX_CLK_SEL1, 0x0); - speed = HS_SPEED_100M; - } - } else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) { - speed = HS_SPEED_100M; - gem_writel(bp, RX_CLK_SEL5, 0x1); - } - - gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, speed, - gem_readl(bp, HS_MAC_CONFIG))); - - return 0; -} - -static int phytium_gem_sel_clk_2(struct macb *bp, int spd) -{ - int speed = 0; - - if (bp->phy_interface == PHY_INTERFACE_MODE_USXGMII || - bp->phy_interface == PHY_INTERFACE_MODE_10GBASER) { - speed = HS_SPEED_10000M; - } else if (bp->phy_interface == PHY_INTERFACE_MODE_5GBASER) { - speed = HS_SPEED_5000M; - } else if (bp->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { - speed = HS_SPEED_2500M; - } else if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { - if (spd == SPEED_1000) { - speed = HS_SPEED_1000M; - } else if (spd == SPEED_100 || spd == SPEED_10) { - speed = HS_SPEED_100M; - } - } - - gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, speed, - gem_readl(bp, HS_MAC_CONFIG))); - - return 0; -} - -static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, +static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, phy_interface_t interface, int speed, int duplex) { @@ -741,12 +594,13 @@ static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, } config &= ~(GEM_BIT(TX_SCR_BYPASS) | GEM_BIT(RX_SCR_BYPASS)); - + /* reset */ config &= ~(GEM_BIT(SIGNAL_OK) | GEM_BIT(TX_EN)); config |= GEM_BIT(RX_SYNC_RESET); gem_writel(bp, USX_CONTROL, config); + /* enable rx and tx */ config &= ~(GEM_BIT(RX_SYNC_RESET)); config |= GEM_BIT(SIGNAL_OK) | GEM_BIT(TX_EN); @@ -761,8 +615,9 @@ static void macb_usx_pcs_get_state(struct phylink_pcs *pcs, if (state->interface == PHY_INTERFACE_MODE_5GBASER) state->speed = SPEED_5000; - else - state->speed = SPEED_10000; + else if (state->interface == PHY_INTERFACE_MODE_10GBASER || + state->interface == PHY_INTERFACE_MODE_USXGMII) + state->speed = bp->speed; state->duplex = 1; state->an_complete = 1; @@ -866,8 +721,8 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode, * Must be written after PCSSEL is set in NCFGR, * otherwise writes will not take effect. */ - if (macb_is_gem(bp) && state->interface == (PHY_INTERFACE_MODE_SGMII || - PHY_INTERFACE_MODE_2500BASEX)) { + if (macb_is_gem(bp) && (state->interface == PHY_INTERFACE_MODE_SGMII || + PHY_INTERFACE_MODE_2500BASEX)) { u32 pcsctrl, old_pcsctrl; old_pcsctrl = gem_readl(bp, PCSCNTRL); @@ -887,9 +742,14 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode, { struct net_device *ndev = to_net_dev(config->dev); struct macb *bp = netdev_priv(ndev); + struct macb_tx_skb *tx_skb; struct macb_queue *queue; unsigned int q; u32 ctrl; + int i; + + if (bp->use_ncsi) + ncsi_stop_dev(bp->ndev); if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) @@ -897,12 +757,172 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode, bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); /* Disable Rx and Tx */ - ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE)) & ~(MACB_BIT(2PT5G)); + ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | + MACB_BIT(TE)) & ~(MACB_BIT(2PT5G)); macb_writel(bp, NCR, ctrl); + /* Tx clean */ + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + for (i = 0; i < bp->tx_ring_size; i++) { + tx_skb = macb_tx_skb(queue, i); + /* free unsent skb buffers */ + if (tx_skb) + macb_tx_unmap(bp, tx_skb, 0); + } + } + netif_tx_stop_all_queues(ndev); } +static void phytium_gem1p0_sel_clk(struct macb *bp, int speed) +{ + if (bp->phy_interface == PHY_INTERFACE_MODE_10GBASER || + bp->phy_interface == PHY_INTERFACE_MODE_USXGMII) { + gem_writel(bp, SRC_SEL_LN, 0x1); /*0x1c04*/ + if (speed == SPEED_5000) { + gem_writel(bp, DIV_SEL0_LN, 0x8); /*0x1c08*/ + gem_writel(bp, DIV_SEL1_LN, 0x2); /*0x1c0c*/ + gem_writel(bp, PMA_XCVR_POWER_STATE, 0x0); /*0x1c10*/ + } else { + gem_writel(bp, DIV_SEL0_LN, 0x4); /*0x1c08*/ + gem_writel(bp, DIV_SEL1_LN, 0x1); /*0x1c0c*/ + gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); /*0x1c10*/ + } + } else if (bp->phy_interface == PHY_INTERFACE_MODE_5GBASER) { + gem_writel(bp, SRC_SEL_LN, 0x1); /*0x1c04*/ + gem_writel(bp, DIV_SEL0_LN, 0x8); /*0x1c08*/ + gem_writel(bp, DIV_SEL1_LN, 0x2); /*0x1c0c*/ + gem_writel(bp, PMA_XCVR_POWER_STATE, 0x0); /*0x1c10*/ + } else if (bp->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { + gem_writel(bp, SRC_SEL_LN, 0x1); /*0x1c04*/ + gem_writel(bp, DIV_SEL0_LN, 0x1); /*0x1c08*/ + gem_writel(bp, DIV_SEL1_LN, 0x2); /*0x1c0c*/ + gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); /*0x1c10*/ + gem_writel(bp, TX_CLK_SEL0, 0x0); /*0x1c20*/ + gem_writel(bp, TX_CLK_SEL1, 0x1); /*0x1c24*/ + gem_writel(bp, TX_CLK_SEL2, 0x1); /*0x1c28*/ + gem_writel(bp, TX_CLK_SEL3, 0x1); /*0x1c2c*/ + gem_writel(bp, RX_CLK_SEL0, 0x1); /*0x1c30*/ + gem_writel(bp, RX_CLK_SEL1, 0x0); /*0x1c34*/ + gem_writel(bp, TX_CLK_SEL3_0, 0x0); /*0x1c70*/ + gem_writel(bp, TX_CLK_SEL4_0, 0x0); /*0x1c74*/ + gem_writel(bp, RX_CLK_SEL3_0, 0x0); /*0x1c78*/ + gem_writel(bp, RX_CLK_SEL4_0, 0x0); /*0x1c7c*/ + } else if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { + if (speed == SPEED_1000) { + gem_writel(bp, SRC_SEL_LN, 0x1); /*0x1c04*/ + gem_writel(bp, DIV_SEL0_LN, 0x4); /*0x1c08*/ + gem_writel(bp, DIV_SEL1_LN, 0x8); /*0x1c0c*/ + gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); /*0x1c10*/ + gem_writel(bp, TX_CLK_SEL0, 0x0); /*0x1c20*/ + gem_writel(bp, TX_CLK_SEL1, 0x0); /*0x1c24*/ + gem_writel(bp, TX_CLK_SEL2, 0x0); /*0x1c28*/ + gem_writel(bp, TX_CLK_SEL3, 0x1); /*0x1c2c*/ + gem_writel(bp, RX_CLK_SEL0, 0x1); /*0x1c30*/ + gem_writel(bp, RX_CLK_SEL1, 0x0); /*0x1c34*/ + gem_writel(bp, TX_CLK_SEL3_0, 0x0); /*0x1c70*/ + gem_writel(bp, TX_CLK_SEL4_0, 0x0); /*0x1c74*/ + gem_writel(bp, RX_CLK_SEL3_0, 0x0); /*0x1c78*/ + gem_writel(bp, RX_CLK_SEL4_0, 0x0); /*0x1c7c*/ + } else if (speed == SPEED_100 || speed == SPEED_10) { + gem_writel(bp, SRC_SEL_LN, 0x1); /*0x1c04*/ + gem_writel(bp, DIV_SEL0_LN, 0x4); /*0x1c08*/ + gem_writel(bp, DIV_SEL1_LN, 0x8); /*0x1c0c*/ + gem_writel(bp, PMA_XCVR_POWER_STATE, 0x1); /*0x1c10*/ + gem_writel(bp, TX_CLK_SEL0, 0x0); /*0x1c20*/ + gem_writel(bp, TX_CLK_SEL1, 0x0); /*0x1c24*/ + gem_writel(bp, TX_CLK_SEL2, 0x1); /*0x1c28*/ + gem_writel(bp, TX_CLK_SEL3, 0x1); /*0x1c2c*/ + gem_writel(bp, RX_CLK_SEL0, 0x1); /*0x1c30*/ + gem_writel(bp, RX_CLK_SEL1, 0x0); /*0x1c34*/ + gem_writel(bp, TX_CLK_SEL3_0, 0x1); /*0x1c70*/ + gem_writel(bp, TX_CLK_SEL4_0, 0x0); /*0x1c74*/ + gem_writel(bp, RX_CLK_SEL3_0, 0x0); /*0x1c78*/ + gem_writel(bp, RX_CLK_SEL4_0, 0x1); /*0x1c7c*/ + } + } else if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII || + bp->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) { + if (speed == SPEED_1000) { + gem_writel(bp, MII_SELECT, 0x1); /*0x1c18*/ + gem_writel(bp, SEL_MII_ON_RGMII, 0x0); /*0x1c1c*/ + gem_writel(bp, TX_CLK_SEL0, 0x0); /*0x1c20*/ + gem_writel(bp, TX_CLK_SEL1, 0x1); /*0x1c24*/ + gem_writel(bp, TX_CLK_SEL2, 0x0); /*0x1c28*/ + gem_writel(bp, TX_CLK_SEL3, 0x0); /*0x1c2c*/ + gem_writel(bp, RX_CLK_SEL0, 0x0); /*0x1c30*/ + gem_writel(bp, RX_CLK_SEL1, 0x1); /*0x1c34*/ + gem_writel(bp, CLK_250M_DIV10_DIV100_SEL, 0x0); /*0x1c38*/ + gem_writel(bp, RX_CLK_SEL5, 0x1); /*0x1c48*/ + gem_writel(bp, RGMII_TX_CLK_SEL0, 0x1); /*0x1c80*/ + gem_writel(bp, RGMII_TX_CLK_SEL1, 0x0); /*0x1c84*/ + } else if (speed == SPEED_100) { + gem_writel(bp, MII_SELECT, 0x1); /*0x1c18*/ + gem_writel(bp, SEL_MII_ON_RGMII, 0x0); /*0x1c1c*/ + gem_writel(bp, TX_CLK_SEL0, 0x0); /*0x1c20*/ + gem_writel(bp, TX_CLK_SEL1, 0x1); /*0x1c24*/ + gem_writel(bp, TX_CLK_SEL2, 0x0); /*0x1c28*/ + gem_writel(bp, TX_CLK_SEL3, 0x0); /*0x1c2c*/ + gem_writel(bp, RX_CLK_SEL0, 0x0); /*0x1c30*/ + gem_writel(bp, RX_CLK_SEL1, 0x1); /*0x1c34*/ + gem_writel(bp, CLK_250M_DIV10_DIV100_SEL, 0x0); /*0x1c38*/ + gem_writel(bp, RX_CLK_SEL5, 0x1); /*0x1c48*/ + gem_writel(bp, RGMII_TX_CLK_SEL0, 0x0); /*0x1c80*/ + gem_writel(bp, RGMII_TX_CLK_SEL1, 0x0); /*0x1c84*/ + } else { + gem_writel(bp, MII_SELECT, 0x1); /*0x1c18*/ + gem_writel(bp, SEL_MII_ON_RGMII, 0x0); /*0x1c1c*/ + gem_writel(bp, TX_CLK_SEL0, 0x0); /*0x1c20*/ + gem_writel(bp, TX_CLK_SEL1, 0x1); /*0x1c24*/ + gem_writel(bp, TX_CLK_SEL2, 0x0); /*0x1c28*/ + gem_writel(bp, TX_CLK_SEL3, 0x0); /*0x1c2c*/ + gem_writel(bp, RX_CLK_SEL0, 0x0); /*0x1c30*/ + gem_writel(bp, RX_CLK_SEL1, 0x1); /*0x1c34*/ + gem_writel(bp, CLK_250M_DIV10_DIV100_SEL, 0x1); /*0x1c38*/ + gem_writel(bp, RX_CLK_SEL5, 0x1); /*0x1c48*/ + gem_writel(bp, RGMII_TX_CLK_SEL0, 0x0); /*0x1c80*/ + gem_writel(bp, RGMII_TX_CLK_SEL1, 0x0); /*0x1c84*/ + } + } else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) { + gem_writel(bp, RX_CLK_SEL5, 0x1); /*0x1c48*/ + } + + if (speed == SPEED_100) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_100M, + gem_readl(bp, HS_MAC_CONFIG))); + else if (speed == SPEED_1000) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_1000M, + gem_readl(bp, HS_MAC_CONFIG))); + else if (speed == SPEED_2500) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_2500M, + gem_readl(bp, HS_MAC_CONFIG))); + else if (speed == SPEED_5000) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_5000M, + gem_readl(bp, HS_MAC_CONFIG))); + else if (speed == SPEED_10000) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_10000M, + gem_readl(bp, HS_MAC_CONFIG))); +} + +static void phytium_gem2p0_sel_clk(struct macb *bp, int speed) +{ + if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { + if (speed == SPEED_100 || speed == SPEED_10) { + gem_writel(bp, SRC_SEL_LN, 0x1); /*0x1c04*/ + gem_writel(bp, DIV_SEL1_LN, 0x1); /*0x1c0c*/ + } + } + + if (speed == SPEED_100 || speed == SPEED_10) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_100M, + gem_readl(bp, HS_MAC_CONFIG))); + else if (speed == SPEED_1000) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_1000M, + gem_readl(bp, HS_MAC_CONFIG))); + else if (speed == SPEED_2500) + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_2500M, + gem_readl(bp, HS_MAC_CONFIG))); +} + static void macb_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, @@ -915,14 +935,12 @@ static void macb_mac_link_up(struct phylink_config *config, unsigned long flags; unsigned int q; u32 ctrl; + int err; spin_lock_irqsave(&bp->lock, flags); - if (bp->caps & MACB_CAPS_SEL_CLK_HW) - phytium_gem_sel_clk(bp, speed); - - if (bp->caps & MACB_CAPS_SEL_CLK_HW_2) - phytium_gem_sel_clk_2(bp, speed); + if (bp->caps & MACB_CAPS_SEL_CLK) + bp->sel_clk_hw(bp, speed); ctrl = macb_or_gem_readl(bp, NCFGR); @@ -946,6 +964,8 @@ static void macb_mac_link_up(struct phylink_config *config, if (rx_pause) ctrl |= MACB_BIT(PAE); + macb_set_tx_clk(bp, speed); + /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down * cleared the pipeline and control registers. */ @@ -959,8 +979,13 @@ static void macb_mac_link_up(struct phylink_config *config, macb_or_gem_writel(bp, NCFGR, ctrl); - if (speed == SPEED_2500) - macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(2PT5G)); + if (speed == SPEED_2500) { + u32 network_ctrl; + + network_ctrl = macb_readl(bp, NCR); + network_ctrl |= MACB_BIT(2PT5G); + macb_writel(bp, NCR, network_ctrl); + } if (bp->phy_interface == PHY_INTERFACE_MODE_10GBASER || bp->phy_interface == PHY_INTERFACE_MODE_USXGMII) { @@ -973,8 +998,9 @@ static void macb_mac_link_up(struct phylink_config *config, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_10000M, gem_readl(bp, HS_MAC_CONFIG))); } else if (bp->phy_interface == PHY_INTERFACE_MODE_5GBASER) - gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, HS_SPEED_5000M, - gem_readl(bp, HS_MAC_CONFIG))); + gem_writel(bp, HS_MAC_CONFIG, + GEM_BFINS(HS_MAC_SPEED, HS_SPEED_5000M, + gem_readl(bp, HS_MAC_CONFIG))); spin_unlock_irqrestore(&bp->lock, flags); @@ -988,6 +1014,15 @@ static void macb_mac_link_up(struct phylink_config *config, macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE)); + if (bp->use_ncsi) { + /* Start the NCSI device */ + err = ncsi_start_dev(bp->ndev); + if (err) { + netdev_err(bp->dev, "Ncsi start dev failed (error %d)\n", err); + return; + } + } + netif_tx_wake_all_queues(ndev); } @@ -999,10 +1034,10 @@ static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config, if (interface == PHY_INTERFACE_MODE_10GBASER || interface == PHY_INTERFACE_MODE_5GBASER || - interface == PHY_INTERFACE_MODE_USXGMII) { + interface == PHY_INTERFACE_MODE_USXGMII) { return &bp->phylink_usx_pcs; } else if (interface == PHY_INTERFACE_MODE_SGMII || - interface == PHY_INTERFACE_MODE_2500BASEX) { + interface == PHY_INTERFACE_MODE_2500BASEX) { return &bp->phylink_sgmii_pcs; } else { return NULL; @@ -1028,7 +1063,7 @@ static int macb_phylink_connect(struct macb *bp) struct device_node *dn = bp->pdev->dev.of_node; struct net_device *dev = bp->dev; struct phy_device *phydev; - int ret = 0; + int ret; if (dn) ret = phylink_of_phy_connect(bp->phylink, dn, 0); @@ -1041,8 +1076,7 @@ static int macb_phylink_connect(struct macb *bp) } /* attach the mac to the phy */ - if (phylink_expects_phy(bp->phylink)) - ret = phylink_connect_phy(bp->phylink, phydev); + ret = phylink_connect_phy(bp->phylink, phydev); } if (ret) { @@ -1550,6 +1584,7 @@ static void gem_rx_refill(struct macb_queue *queue) /* Make hw descriptor updates visible to CPU */ rmb(); + queue->rx_prepared_head++; desc = macb_rx_desc(queue, entry); if (!queue->rx_skbuff[entry]) { @@ -1588,7 +1623,6 @@ static void gem_rx_refill(struct macb_queue *queue) dma_wmb(); desc->addr &= ~MACB_BIT(RX_USED); } - queue->rx_prepared_head++; } /* Make descriptor updates visible to hardware */ @@ -2125,11 +2159,10 @@ static irqreturn_t gem_wol_interrupt(int irq, void *dev_id) static irqreturn_t macb_interrupt(int irq, void *dev_id) { - struct macb_queue *qq, *queue = dev_id; + struct macb_queue *queue = dev_id; struct macb *bp = queue->bp; struct net_device *dev = bp->dev; u32 status, ctrl; - unsigned int q; status = queue_readl(queue, ISR); @@ -2176,13 +2209,11 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) MACB_BIT(TXUBR)); if (status & MACB_BIT(TXUBR)) { - for (q = 0, qq = bp->queues; q < bp->num_queues; q++, qq++) { - qq->txubr_pending = true; - wmb(); // ensure softirq can see update - if (napi_schedule_prep(&qq->napi_tx)) - __napi_schedule(&qq->napi_tx); - } - } else if (napi_schedule_prep(&queue->napi_tx)) { + queue->txubr_pending = true; + wmb(); // ensure softirq can see update + } + + if (napi_schedule_prep(&queue->napi_tx)) { netdev_vdbg(bp->dev, "scheduling TX softirq\n"); __napi_schedule(&queue->napi_tx); } @@ -2630,8 +2661,6 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev) wmb(); skb_tx_timestamp(skb); - if (bp->caps & MACB_CAPS_TAILPTR) - queue_writel(queue, TAILADDR, BIT(31) | macb_tx_ring_wrap(bp, queue->tx_head)); spin_lock_irq(&bp->lock); macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); spin_unlock_irq(&bp->lock); @@ -2712,27 +2741,48 @@ static void macb_free_rx_buffers(struct macb *bp) static void macb_free_consistent(struct macb *bp) { + struct macb_dma_desc *tx_ring_base = NULL; + struct macb_dma_desc *rx_ring_base = NULL; + dma_addr_t tx_ring_base_addr; + dma_addr_t rx_ring_base_addr; struct macb_queue *queue; unsigned int q; int size; bp->macbgem_ops.mog_free_rx_buffers(bp); + queue = bp->queues; + if (queue->tx_ring) { + tx_ring_base = queue->tx_ring; + tx_ring_base_addr = queue->tx_ring_dma; + } + if (queue->rx_ring) { + rx_ring_base = queue->rx_ring; + rx_ring_base_addr = queue->rx_ring_dma; + } + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { kfree(queue->tx_skb); queue->tx_skb = NULL; - if (queue->tx_ring) { - size = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch; - dma_free_coherent(&bp->pdev->dev, size, - queue->tx_ring, queue->tx_ring_dma); + if (queue->tx_ring) queue->tx_ring = NULL; - } - if (queue->rx_ring) { - size = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch; - dma_free_coherent(&bp->pdev->dev, size, - queue->rx_ring, queue->rx_ring_dma); + if (queue->rx_ring) queue->rx_ring = NULL; - } + } + + if (tx_ring_base) { + size = bp->num_queues * (TX_RING_BYTES(bp) + + bp->tx_bd_rd_prefetch + + RING_ADDR_INTERVAL); + dma_free_coherent(&bp->pdev->dev, size, tx_ring_base, + tx_ring_base_addr); + } + if (rx_ring_base) { + size = bp->num_queues * (RX_RING_BYTES(bp) + + bp->rx_bd_rd_prefetch + + RING_ADDR_INTERVAL); + dma_free_coherent(&bp->pdev->dev, size, rx_ring_base, + rx_ring_base_addr); } } @@ -2772,17 +2822,87 @@ static int macb_alloc_rx_buffers(struct macb *bp) return 0; } +static int macb_queue_phyaddr_check(struct macb *bp, dma_addr_t ring_base_addr, + int offset) +{ + u32 bus_addr_high; + int i; + + bus_addr_high = upper_32_bits(ring_base_addr); + for (i = 1; i < bp->num_queues; i++) { + ring_base_addr += offset; + if (bus_addr_high != upper_32_bits(ring_base_addr)) + return -1; + } + + return 0; +} + static int macb_alloc_consistent(struct macb *bp) { + struct macb_dma_desc *tx_ring_base, *rx_ring_base; + dma_addr_t tx_ring_base_addr, rx_ring_base_addr; struct macb_queue *queue; + int tx_offset, rx_offset; + int tx_size, rx_size; unsigned int q; + int ret, i; int size; + tx_offset = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch + + RING_ADDR_INTERVAL; + tx_size = bp->num_queues * tx_offset; + for (i = 0; i < MAX_RING_ADDR_ALLOC_TIMES + 1; i++) { + if (i == MAX_RING_ADDR_ALLOC_TIMES) + return -ENOMEM; + + tx_ring_base = dma_alloc_coherent(&bp->pdev->dev, tx_size, + &tx_ring_base_addr, + GFP_KERNEL); + if (!tx_ring_base) + continue; + + ret = macb_queue_phyaddr_check(bp, tx_ring_base_addr, + tx_offset); + if (ret) { + dma_free_coherent(&bp->pdev->dev, tx_size, tx_ring_base, + tx_ring_base_addr); + continue; + } else { + break; + } + } + + rx_offset = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch + + RING_ADDR_INTERVAL; + rx_size = bp->num_queues * rx_offset; + for (i = 0; i < MAX_RING_ADDR_ALLOC_TIMES + 1; i++) { + if (i == MAX_RING_ADDR_ALLOC_TIMES) { + dma_free_coherent(&bp->pdev->dev, tx_size, tx_ring_base, + tx_ring_base_addr); + return -ENOMEM; + } + + rx_ring_base = dma_alloc_coherent(&bp->pdev->dev, rx_size, + &rx_ring_base_addr, + GFP_KERNEL); + if (!rx_ring_base) + continue; + + ret = macb_queue_phyaddr_check(bp, rx_ring_base_addr, + rx_offset); + if (ret) { + dma_free_coherent(&bp->pdev->dev, rx_size, rx_ring_base, + rx_ring_base_addr); + continue; + } else { + break; + } + } + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { - size = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch; - queue->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size, - &queue->tx_ring_dma, - GFP_KERNEL); + queue->tx_ring = (void *)tx_ring_base + q * tx_offset; + queue->tx_ring_dma = tx_ring_base_addr + q * tx_offset; if (!queue->tx_ring) goto out_err; netdev_dbg(bp->dev, @@ -2791,13 +2911,12 @@ static int macb_alloc_consistent(struct macb *bp) queue->tx_ring); size = bp->tx_ring_size * sizeof(struct macb_tx_skb); - queue->tx_skb = kmalloc(size, GFP_KERNEL); + queue->tx_skb = kzalloc(size, GFP_KERNEL); if (!queue->tx_skb) goto out_err; - size = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch; - queue->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size, - &queue->rx_ring_dma, GFP_KERNEL); + queue->rx_ring = (void *)rx_ring_base + q * rx_offset; + queue->rx_ring_dma = rx_ring_base_addr + q * rx_offset; if (!queue->rx_ring) goto out_err; netdev_dbg(bp->dev, @@ -2831,9 +2950,15 @@ static void gem_init_rings(struct macb *bp) queue->tx_head = 0; queue->tx_tail = 0; - if (bp->caps & MACB_CAPS_TAILPTR) - queue_writel(queue, TAILADDR, BIT(31) | queue->tx_head); - + for (i = 0; i < bp->rx_ring_size; i++) { + desc = macb_rx_desc(queue, i); + desc->ctrl = 0; + /* make sure ctrl is cleared first, + * and bit RX_USED is set to avoid a race. + */ + dma_wmb(); + desc->addr |= MACB_BIT(RX_USED); + } queue->rx_tail = 0; queue->rx_prepared_head = 0; @@ -3010,6 +3135,46 @@ static void macb_configure_dma(struct macb *bp) } } +static int phytium_mac_config(struct macb *bp) +{ + u32 old_ctrl, ctrl; + u32 old_ncr, ncr; + + netdev_dbg(bp->dev, "phytium mac config"); + + ncr = macb_readl(bp, NCR); + old_ncr = ncr; + ctrl = macb_or_gem_readl(bp, NCFGR); + old_ctrl = ctrl; + + ncr &= ~(GEM_BIT(ENABLE_HS_MAC) | MACB_BIT(2PT5G)); + ctrl &= ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL) | + MACB_BIT(SPD) | MACB_BIT(FD)); + if (macb_is_gem(bp)) + ctrl &= ~GEM_BIT(GBE); + + if (bp->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { + ctrl |= GEM_BIT(PCSSEL) | GEM_BIT(SGMIIEN); + ncr |= MACB_BIT(2PT5G); + } else if (bp->phy_interface == PHY_INTERFACE_MODE_USXGMII || + bp->phy_interface == PHY_INTERFACE_MODE_5GBASER) { + ctrl |= GEM_BIT(PCSSEL); + ncr |= GEM_BIT(ENABLE_HS_MAC); + } + + if (bp->duplex) + ctrl |= MACB_BIT(FD); + + /* Apply the new configuration, if any */ + if (old_ctrl ^ ctrl) + macb_or_gem_writel(bp, NCFGR, ctrl); + + if (old_ncr ^ ncr) + macb_or_gem_writel(bp, NCR, ncr); + + return 0; +} + static void macb_init_hw(struct macb *bp) { u32 config; @@ -3039,14 +3204,23 @@ static void macb_init_hw(struct macb *bp) bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK; gem_writel(bp, AXI_PIPE, 0x1010); - if (bp->caps & MACB_CAPS_TAILPTR) - gem_writel(bp, TAIL_ENABLE, 0x80000001); - macb_configure_dma(bp); + if (bp->phy_interface == PHY_INTERFACE_MODE_USXGMII || + bp->phy_interface == PHY_INTERFACE_MODE_5GBASER || + bp->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { + /* phytium need hwclock */ + if (bp->caps & MACB_CAPS_SEL_CLK) + bp->sel_clk_hw(bp, bp->speed); + phytium_mac_config(bp); + if (bp->link) + macb_usx_pcs_link_up(&bp->phylink_usx_pcs, 0, + bp->phy_interface, bp->speed, bp->duplex); + } else { + bp->speed = SPEED_10; + bp->duplex = DUPLEX_HALF; + } - /* Enable RX partial store and forward and set watermark */ - if (bp->rx_watermark) - gem_writel(bp, PBUFRXCUT, (bp->rx_watermark | GEM_BIT(ENCUTTHRU))); + macb_configure_dma(bp); } /* The hash address register is 64 bits long and takes up two @@ -3170,10 +3344,7 @@ static void macb_set_rx_mode(struct net_device *dev) static int macb_open(struct net_device *dev) { - /* adjust bufsz to be at least the size of a standard frame, - * to fix rx error when set small size mtu. - */ - size_t bufsz = (dev->mtu < ETH_DATA_LEN ? ETH_DATA_LEN : dev->mtu) + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN; + size_t bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN; struct macb *bp = netdev_priv(dev); struct macb_queue *queue; unsigned int q; @@ -3202,24 +3373,13 @@ static int macb_open(struct net_device *dev) macb_init_hw(bp); - if (bp->use_ncsi) { - /* If using NC-SI, set our carrier on and start the stack */ - netif_carrier_on(dev); - - /* Start the NCSI device */ - err = ncsi_start_dev(bp->ndev); - if (err) { - netdev_err(dev, "NCSI start dev failed (error %d)\n", err); - } - } else { - err = phy_power_on(bp->sgmii_phy); - if (err) - goto reset_hw; + err = phy_power_on(bp->sgmii_phy); + if (err) + goto reset_hw; - err = macb_phylink_connect(bp); - if (err) - goto phy_off; - } + err = macb_phylink_connect(bp); + if (err) + goto phy_off; netif_tx_start_all_queues(dev); @@ -3262,9 +3422,6 @@ static int macb_close(struct net_device *dev) phy_power_off(bp->sgmii_phy); - if (bp->use_ncsi) - ncsi_stop_dev(bp->ndev); - spin_lock_irqsave(&bp->lock, flags); macb_reset_hw(bp); netif_carrier_off(dev); @@ -4313,6 +4470,97 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, return err; } +static int phytium_clk_init(struct platform_device *pdev, struct clk **pclk, + struct clk **hclk, struct clk **tx_clk, + struct clk **rx_clk, struct clk **tsu_clk) +{ + struct macb_platform_data *pdata; + struct device_node *np = pdev->dev.of_node; + int err; + + pdata = dev_get_platdata(&pdev->dev); + if (pdata) { + *pclk = pdata->pclk; + *hclk = pdata->hclk; + } else { + if (has_acpi_companion(&pdev->dev)) { + *pclk = NULL; + *hclk = NULL; + } else if (np) { + *pclk = devm_clk_get(&pdev->dev, "pclk"); + *hclk = devm_clk_get(&pdev->dev, "hclk"); + } + } + + if (IS_ERR(*pclk)) + return dev_err_probe(&pdev->dev, + IS_ERR(*pclk) ? PTR_ERR(*pclk) : -ENODEV, + "failed to get pclk\n"); + + if (IS_ERR(*hclk)) + return dev_err_probe(&pdev->dev, + IS_ERR(*hclk) ? PTR_ERR(*hclk) : -ENODEV, + "failed to get hclk\n"); + + *tx_clk = devm_clk_get_optional(&pdev->dev, "tx_clk"); + if (IS_ERR(*tx_clk)) + return PTR_ERR(*tx_clk); + + *rx_clk = devm_clk_get_optional(&pdev->dev, "rx_clk"); + if (IS_ERR(*rx_clk)) + return PTR_ERR(*rx_clk); + + *tsu_clk = devm_clk_get_optional(&pdev->dev, "tsu_clk"); + if (IS_ERR(*tsu_clk)) + return PTR_ERR(*tsu_clk); + + err = clk_prepare_enable(*pclk); + if (err) { + dev_err(&pdev->dev, "failed to enable pclk (%d)\n", err); + return err; + } + + err = clk_prepare_enable(*hclk); + if (err) { + dev_err(&pdev->dev, "failed to enable hclk (%d)\n", err); + goto err_disable_pclk; + } + + err = clk_prepare_enable(*tx_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable tx_clk (%d)\n", err); + goto err_disable_hclk; + } + + err = clk_prepare_enable(*rx_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable rx_clk (%d)\n", err); + goto err_disable_txclk; + } + + err = clk_prepare_enable(*tsu_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable tsu_clk (%d)\n", err); + goto err_disable_rxclk; + } + + return 0; + +err_disable_rxclk: + clk_disable_unprepare(*rx_clk); + +err_disable_txclk: + clk_disable_unprepare(*tx_clk); + +err_disable_hclk: + clk_disable_unprepare(*hclk); + +err_disable_pclk: + clk_disable_unprepare(*pclk); + + return err; +} + static int macb_init(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); @@ -4367,8 +4615,7 @@ static int macb_init(struct platform_device *pdev) } #endif } - if (bp->caps & MACB_CAPS_TAILPTR) - queue->TAILADDR = GEM_TAIL(hw_q); + /* get irq: here we use the linux queue index, not the hardware * queue index. the queue irq definitions in the device tree * must remove the optional gaps that could exist in the @@ -4392,12 +4639,14 @@ static int macb_init(struct platform_device *pdev) /* setup appropriated routines according to adapter type */ if (macb_is_gem(bp)) { + bp->max_tx_length = GEM_MAX_TX_LEN; bp->macbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers; bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers; bp->macbgem_ops.mog_init_rings = gem_init_rings; bp->macbgem_ops.mog_rx = gem_rx; dev->ethtool_ops = &gem_ethtool_ops; } else { + bp->max_tx_length = MACB_MAX_TX_LEN; bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers; bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers; bp->macbgem_ops.mog_init_rings = macb_init_rings; @@ -4417,12 +4666,6 @@ static int macb_init(struct platform_device *pdev) /* Checksum offload is only available on gem with packet buffer */ if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE)) dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; - - if (bp->use_ncsi) { - dev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM); - dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; - } - if (bp->caps & MACB_CAPS_SG_DISABLED) dev->hw_features &= ~NETIF_F_SG; dev->features = dev->hw_features; @@ -5023,57 +5266,6 @@ static int init_reset_optional(struct platform_device *pdev) return ret; } -#define PHYTIUM_PCLK_RATE 250000000 -#define PHYTIUM_HCLK_RATE 48000000 - -static int phytium_clk_init(struct platform_device *pdev, struct clk **pclk, - struct clk **hclk, struct clk **tx_clk, - struct clk **rx_clk, struct clk **tsu_clk) -{ - struct macb_platform_data plat_data; - int err = 0; - - if (has_acpi_companion(&pdev->dev)) { - char clk_name[20]; - /* set up macb platform data */ - memset(&plat_data, 0, sizeof(plat_data)); - - /* initialize clocks */ - snprintf(clk_name, 20, "%s-pclk", pdev->name); - plat_data.pclk = clk_register_fixed_rate(&pdev->dev, clk_name, NULL, 0, - PHYTIUM_PCLK_RATE); - if (IS_ERR(plat_data.pclk)) { - err = PTR_ERR(plat_data.pclk); - goto err_pclk_register; - } - - snprintf(clk_name, 20, "%s-hclk", pdev->name); - plat_data.hclk = clk_register_fixed_rate(&pdev->dev, clk_name, NULL, 0, - PHYTIUM_HCLK_RATE); - if (IS_ERR(plat_data.hclk)) { - err = PTR_ERR(plat_data.hclk); - goto err_hclk_register; - } - - err = platform_device_add_data(pdev, &plat_data, sizeof(plat_data)); - if (err) - goto err_plat_dev_register; - } - - err = macb_clk_init(pdev, pclk, hclk, tx_clk, rx_clk, tsu_clk); - - return 0; - -err_plat_dev_register: - clk_unregister(plat_data.hclk); - -err_hclk_register: - clk_unregister(plat_data.pclk); - -err_pclk_register: - return err; -} - static const struct macb_usrio_config sama7g5_usrio = { .mii = 0, .rmii = 1, @@ -5224,25 +5416,31 @@ static const struct macb_config versal_config = { .usrio = &macb_default_usrio, }; -static const struct macb_config phytium_config = { - .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO | - MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH | - MACB_CAPS_SEL_CLK_HW, +static const struct macb_config phytium_gem1p0_config = { + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | + MACB_CAPS_JUMBO | + MACB_CAPS_GEM_HAS_PTP | + MACB_CAPS_BD_RD_PREFETCH | + MACB_CAPS_SEL_CLK, .dma_burst_length = 16, .clk_init = phytium_clk_init, .init = macb_init, - .jumbo_max_len = 16360, + .jumbo_max_len = 10240, + .sel_clk_hw = phytium_gem1p0_sel_clk, .usrio = &macb_default_usrio, }; -static const struct macb_config phytium_gmac_config = { - .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO | - MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH | - MACB_CAPS_SEL_CLK_HW_2 | MACB_CAPS_TAILPTR, +static const struct macb_config phytium_gem2p0_config = { + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | + MACB_CAPS_JUMBO | + MACB_CAPS_GEM_HAS_PTP | + MACB_CAPS_BD_RD_PREFETCH | + MACB_CAPS_SEL_CLK, .dma_burst_length = 16, .clk_init = phytium_clk_init, .init = macb_init, .jumbo_max_len = 10240, + .sel_clk_hw = phytium_gem2p0_sel_clk, .usrio = &macb_default_usrio, }; @@ -5269,8 +5467,8 @@ static const struct of_device_id macb_dt_ids[] = { { .compatible = "xlnx,zynqmp-gem", .data = &zynqmp_config}, { .compatible = "xlnx,zynq-gem", .data = &zynq_config }, { .compatible = "xlnx,versal-gem", .data = &versal_config}, - { .compatible = "cdns,phytium-gem", .data = &phytium_config }, - { .compatible = "phytium,gmac-1.0", .data = &phytium_gmac_config }, + { .compatible = "cdns,phytium-gem-1.0", .data = &phytium_gem1p0_config }, + { .compatible = "cdns,phytium-gem-2.0", .data = &phytium_gem2p0_config }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, macb_dt_ids); @@ -5278,8 +5476,7 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids); #ifdef CONFIG_ACPI static const struct acpi_device_id macb_acpi_ids[] = { - { .id = "PHYT0036", .driver_data = (kernel_ulong_t)&phytium_config }, - { .id = "PHYT0046", .driver_data = (kernel_ulong_t)&phytium_gmac_config }, + { .id = "PHYT0036", .driver_data = (kernel_ulong_t)&phytium_gem1p0_config }, { } }; @@ -5299,17 +5496,6 @@ static const struct macb_config default_gem_config = { .jumbo_max_len = 10240, }; -static void macb_destroy_mdio(struct net_device *dev) -{ - struct macb *bp = netdev_priv(dev); - - if (!bp->mii_bus) - return; - - mdiobus_unregister(bp->mii_bus); - mdiobus_free(bp->mii_bus); -} - static void gem_ncsi_handler(struct ncsi_dev *nd) { if (unlikely(nd->state != ncsi_dev_state_functional)) @@ -5319,22 +5505,19 @@ static void gem_ncsi_handler(struct ncsi_dev *nd) nd->link_up ? "up" : "down"); } -static int macb_get_phy_mode(struct platform_device *pdev, phy_interface_t *interface) +static int macb_get_phy_mode(struct platform_device *pdev) { const char *pm; int err, i; err = device_property_read_string(&pdev->dev, "phy-mode", &pm); - if (err < 0) - err = device_property_read_string(&pdev->dev, "phy-connection-type", &pm); if (err < 0) return err; - for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) - if (!strcasecmp(pm, phy_modes(i))) { - *interface = i; - return 0; - } + for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) { + if (!strcasecmp(pm, phy_modes(i))) + return i; + } return -ENODEV; } @@ -5351,7 +5534,6 @@ static int macb_probe(struct platform_device *pdev) struct clk *tsu_clk = NULL; unsigned int queue_mask, num_queues; bool native_io; - phy_interface_t interface; struct net_device *dev; struct resource *regs; u32 wtrmrk_rst_val; @@ -5429,6 +5611,9 @@ static int macb_probe(struct platform_device *pdev) if (macb_config) bp->jumbo_max_len = macb_config->jumbo_max_len; + if (macb_config) + bp->sel_clk_hw = macb_config->sel_clk_hw; + if (!hw_is_gem(bp->regs, bp->native_io)) bp->max_tx_length = MACB_MAX_TX_LEN; else if (macb_config->max_tx_length) @@ -5510,37 +5695,33 @@ static int macb_probe(struct platform_device *pdev) else if (err) macb_get_hwaddr(bp); - err = macb_get_phy_mode(pdev, &interface); - if (err) - /* not found in DT, MII by default */ + err = macb_get_phy_mode(pdev); + if (err < 0) bp->phy_interface = PHY_INTERFACE_MODE_MII; else - bp->phy_interface = interface; + bp->phy_interface = err; + /* IP specific init */ err = init(pdev); if (err) goto err_out_free_netdev; + err = macb_mii_init(bp); + if (err) + goto err_out_phy_exit; + if (device_property_read_bool(&pdev->dev, "use-ncsi")) { if (!IS_ENABLED(CONFIG_NET_NCSI)) { dev_err(&pdev->dev, "NCSI stack not enabled\n"); - err = -EINVAL; goto err_out_free_netdev; } - dev_notice(&pdev->dev, "Using NCSI interface\n"); bp->use_ncsi = 1; bp->ndev = ncsi_register_dev(dev, gem_ncsi_handler); - if (!bp->ndev) { - err = -EINVAL; + if (!bp->ndev) goto err_out_free_netdev; - } } else { - err = macb_mii_init(bp); - if (err) - goto err_out_phy_exit; - bp->use_ncsi = 0; } @@ -5564,9 +5745,8 @@ static int macb_probe(struct platform_device *pdev) return 0; err_out_unregister_mdio: - if (bp->ndev) - ncsi_unregister_dev(bp->ndev); - macb_destroy_mdio(dev); + mdiobus_unregister(bp->mii_bus); + mdiobus_free(bp->mii_bus); err_out_phy_exit: phy_exit(bp->sgmii_phy); @@ -5593,9 +5773,8 @@ static int macb_remove(struct platform_device *pdev) if (dev) { bp = netdev_priv(dev); phy_exit(bp->sgmii_phy); - macb_destroy_mdio(dev); - if (bp->ndev) - ncsi_unregister_dev(bp->ndev); + mdiobus_unregister(bp->mii_bus); + mdiobus_free(bp->mii_bus); unregister_netdev(dev); tasklet_kill(&bp->hresp_err_tasklet); @@ -5777,6 +5956,8 @@ static int __maybe_unused macb_resume(struct device *dev) macb_set_rx_mode(netdev); macb_restore_features(bp); rtnl_lock(); + if (!device_may_wakeup(&bp->dev->dev)) + phy_init(bp->sgmii_phy); phylink_start(bp->phylink); rtnl_unlock(); -- Gitee From cd5d98e4af86e3f60853976cde54e3ea0fb2b7fd Mon Sep 17 00:00:00 2001 From: Liu Tianyu Date: Mon, 25 Mar 2024 15:50:31 +0800 Subject: [PATCH 21/71] spi: Phytium: Adapt SPI driver to use DDMA interface V2 Code has been modified and added in the SPI driver section to adapt to the DDMA controller. Signed-off-by: Liu Tianyu Signed-off-by: Wang Hanmo Signed-off-by: Wang Yinfeng Change-Id: I132356ba589c37287a890be971413d724e47a144 --- MAINTAINERS | 1 + drivers/spi/Makefile | 3 +- drivers/spi/spi-phytium-dma.c | 61 ++++++++++++++++++++++++++-------- drivers/spi/spi-phytium-pci.c | 6 ++-- drivers/spi/spi-phytium-plat.c | 8 ++--- drivers/spi/spi-phytium.c | 15 +++++---- drivers/spi/spi-phytium.h | 31 ++++------------- 7 files changed, 73 insertions(+), 52 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index e02a06d96a6..dbf220d4f51 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17472,6 +17472,7 @@ F: drivers/net/can/phytium/* F: drivers/pci/controller/pcie-phytium* F: drivers/pwm/pwm-phytium.c F: drivers/spi/spi-phytium* +F: drivers/spi/spi-phytium-dma.c F: drivers/spi/spi-phytium-qspi.c F: drivers/tty/serial/phytium-uart.c F: drivers/usb/phytium/* diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 3c431de8636..cfaf68b2d39 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -101,10 +101,11 @@ obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o obj-$(CONFIG_SPI_ORION) += spi-orion.o obj-$(CONFIG_SPI_PCI1XXXX) += spi-pci1xxxx.o -obj-$(CONFIG_SPI_PHYTIUM) += spi-phytium.o spi-phytium-dma.o +obj-$(CONFIG_SPI_PHYTIUM) += spi-phytium.o obj-$(CONFIG_SPI_PHYTIUM_PLAT) += spi-phytium-plat.o obj-$(CONFIG_SPI_PHYTIUM_PCI) += spi-phytium-pci.o obj-$(CONFIG_SPI_PHYTIUM_QSPI) += spi-phytium-qspi.o +obj-$(CONFIG_SPI_PHYTIUM) += spi-phytium-dma.o obj-$(CONFIG_SPI_PIC32) += spi-pic32.o obj-$(CONFIG_SPI_PIC32_SQI) += spi-pic32-sqi.o obj-$(CONFIG_SPI_PL022) += spi-pl022.o diff --git a/drivers/spi/spi-phytium-dma.c b/drivers/spi/spi-phytium-dma.c index 0a18c8b7140..25693b63395 100644 --- a/drivers/spi/spi-phytium-dma.c +++ b/drivers/spi/spi-phytium-dma.c @@ -46,13 +46,24 @@ static void phytium_spi_dma_maxburst_init(struct phytium_spi *fts) else max_burst = TX_BURST_LEVEL; + /* + * Having a Rx DMA channel serviced with higher priority than a Tx DMA + * channel might not be enough to provide a well balanced DMA-based + * SPI transfer interface. There might still be moments when the Tx DMA + * channel is occasionally handled faster than the Rx DMA channel. + * That in its turn will eventually cause the SPI Rx FIFO overflow if + * SPI bus speed is high enough to fill the SPI Rx FIFO in before it's + * cleared by the Rx DMA channel. In order to fix the problem the Tx + * DMA activity is intentionally slowed down by limiting the SPI Tx + * FIFO depth with a value twice bigger than the Tx burst length. + */ fts->txburst = min(max_burst, def_burst); /* set dmatdlr to 0 + 1 */ phytium_writel(fts, DMATDLR, 0); } static int phytium_spi_dma_init(struct device *dev, - struct phytium_spi *fts) + struct phytium_spi *fts) { fts->rxchan = dma_request_chan(dev, "rx"); if (IS_ERR_OR_NULL(fts->rxchan)) @@ -89,8 +100,8 @@ static void phytium_spi_dma_exit(struct phytium_spi *fts) } } -static irqreturn_t -phytium_spi_dma_transfer_handler(struct phytium_spi *fts) +static irqreturn_t phytium_spi_dma_transfer_handler +(struct phytium_spi *fts) { phytium_spi_check_status(fts, false); @@ -100,7 +111,7 @@ phytium_spi_dma_transfer_handler(struct phytium_spi *fts) } static bool phytium_spi_can_dma(struct spi_controller *master, - struct spi_device *spi, struct spi_transfer *xfer) + struct spi_device *spi, struct spi_transfer *xfer) { struct phytium_spi *fts = spi_controller_get_devdata(master); @@ -118,7 +129,7 @@ static enum dma_slave_buswidth phytium_spi_dma_convert_width(u8 n_bytes) } static int phytium_spi_dma_wait(struct phytium_spi *fts, unsigned int len, - u32 speed) + u32 speed) { unsigned long long ms; @@ -150,7 +161,6 @@ static void spi_transfer_delay_ns(u32 ns) { if (!ns) return; - if (ns <= 1000) { ndelay(ns); } else { @@ -164,7 +174,7 @@ static void spi_transfer_delay_ns(u32 ns) } static int phytium_spi_dma_wait_tx_done(struct phytium_spi *fts, - struct spi_transfer *xfer) + struct spi_transfer *xfer) { int retry = SPI_WAIT_RETRIES; u32 ns = 0; @@ -185,6 +195,11 @@ static int phytium_spi_dma_wait_tx_done(struct phytium_spi *fts, return 0; } +/* + * fts->dma_chan_busy is set before the dma transfer starts, + * callback for tx + * channel will clear a corresponding bit. + */ static void phytium_spi_dma_tx_done(void *arg) { struct phytium_spi *fts = arg; @@ -212,7 +227,7 @@ static int phytium_spi_dma_config_tx(struct phytium_spi *fts) } static int phytium_spi_dma_submit_tx(struct phytium_spi *fts, - struct scatterlist *sgl, unsigned int nents) + struct scatterlist *sgl, unsigned int nents) { struct dma_async_tx_descriptor *txdesc; dma_cookie_t cookie; @@ -250,6 +265,15 @@ static int phytium_spi_dma_wait_rx_done(struct phytium_spi *fts) unsigned long ns = 0; u32 nents = 0; + /* + * It's unlikely that DMA engine is still doing the data fetching, but + * if it's let's give it some reasonable time. The timeout calculation + * is based on the synchronous APB/SSI reference clock rate, on a + * number of data entries left in the Rx FIFO, times a number of clock + * periods normally needed for a single APB read/write transaction + * without PREADY signal utilized (which is true for the phytium APB SSI + * controller). + */ nents = phytium_readl(fts, RXFLR); ns = 4U * NSEC_PER_SEC / fts->max_freq * nents; @@ -264,6 +288,11 @@ static int phytium_spi_dma_wait_rx_done(struct phytium_spi *fts) return 0; } +/* + * fts->dma_chan_busy is set before the dma transfer starts, + * callback for rx + * channel will clear a corresponding bit. + */ static void phytium_spi_dma_rx_done(void *arg) { struct phytium_spi *fts = arg; @@ -291,7 +320,7 @@ static int phytium_spi_dma_config_rx(struct phytium_spi *fts) } static int phytium_spi_dma_submit_rx(struct phytium_spi *fts, - struct scatterlist *sgl, unsigned int nents) + struct scatterlist *sgl, unsigned int nents) { struct dma_async_tx_descriptor *rxdesc; dma_cookie_t cookie; @@ -319,7 +348,7 @@ static int phytium_spi_dma_submit_rx(struct phytium_spi *fts, } static int phytium_spi_dma_setup(struct phytium_spi *fts, - struct spi_transfer *xfer) + struct spi_transfer *xfer) { u16 imr, dma_ctrl; int ret; @@ -359,7 +388,7 @@ static int phytium_spi_dma_setup(struct phytium_spi *fts, } static int phytium_spi_dma_transfer_all(struct phytium_spi *fts, - struct spi_transfer *xfer) + struct spi_transfer *xfer) { int ret; @@ -391,7 +420,7 @@ static int phytium_spi_dma_transfer_all(struct phytium_spi *fts, } static int phytium_spi_dma_transfer_one(struct phytium_spi *fts, - struct spi_transfer *xfer) + struct spi_transfer *xfer) { struct scatterlist *tx_sg = NULL, *rx_sg = NULL, tx_tmp, rx_tmp; unsigned int tx_len = 0, rx_len = 0; @@ -441,6 +470,12 @@ static int phytium_spi_dma_transfer_one(struct phytium_spi *fts, dma_async_issue_pending(fts->txchan); + /* + * Here we only need to wait for the DMA transfer to be + * finished since SPI controller is kept enabled during the + * procedure this loop implements and there is no risk to lose + * data left in the Tx/Rx FIFOs. + */ ret = phytium_spi_dma_wait(fts, len, xfer->speed_hz); if (ret) break; @@ -459,7 +494,7 @@ static int phytium_spi_dma_transfer_one(struct phytium_spi *fts, } static int phytium_spi_dma_transfer(struct phytium_spi *fts, - struct spi_transfer *xfer) + struct spi_transfer *xfer) { unsigned int nents; int ret; diff --git a/drivers/spi/spi-phytium-pci.c b/drivers/spi/spi-phytium-pci.c index 54032b429b9..6ef8acfe5c8 100644 --- a/drivers/spi/spi-phytium-pci.c +++ b/drivers/spi/spi-phytium-pci.c @@ -88,14 +88,16 @@ static void phytium_spi_pci_remove(struct pci_dev *pdev) #ifdef CONFIG_PM_SLEEP static int spi_suspend(struct device *dev) { - struct phytium_spi *fts = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + struct phytium_spi *fts = spi_master_get_devdata(master); return phytium_spi_suspend_host(fts); } static int spi_resume(struct device *dev) { - struct phytium_spi *fts = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + struct phytium_spi *fts = spi_master_get_devdata(master); return phytium_spi_resume_host(fts); } diff --git a/drivers/spi/spi-phytium-plat.c b/drivers/spi/spi-phytium-plat.c index 8b8570c7e19..9b82c5c0160 100644 --- a/drivers/spi/spi-phytium-plat.c +++ b/drivers/spi/spi-phytium-plat.c @@ -88,16 +88,16 @@ static int phytium_spi_probe(struct platform_device *pdev) device_property_read_u32(&pdev->dev, "reg-io-width", &fts->reg_io_width); num_cs = 4; - device_property_read_u32(&pdev->dev, "num-cs", &num_cs); - fts->num_cs = num_cs; device_property_read_u32(&pdev->dev, "global-cs", &global_cs); fts->global_cs = global_cs; - if ((device_property_read_string_array(&pdev->dev, "dma-names", NULL, 0) > 0) && - device_property_present(&pdev->dev, "dmas")) { + /* check is use dma transfer */ + if ((device_property_read_string_array(&pdev->dev, "dma-names", + NULL, 0) > 0) && + device_property_present(&pdev->dev, "dmas")) { fts->dma_en = true; phytium_spi_dmaops_set(fts); } diff --git a/drivers/spi/spi-phytium.c b/drivers/spi/spi-phytium.c index be7073a3e35..131baeacdcd 100644 --- a/drivers/spi/spi-phytium.c +++ b/drivers/spi/spi-phytium.c @@ -119,7 +119,6 @@ static void phytium_reader(struct phytium_spi *fts) fts->rx += fts->n_bytes; } } - int phytium_spi_check_status(struct phytium_spi *fts, bool raw) { u32 irq_status; @@ -151,7 +150,6 @@ int phytium_spi_check_status(struct phytium_spi *fts, bool raw) if (fts->master->cur_msg) fts->master->cur_msg->status = ret; } - return ret; } EXPORT_SYMBOL_GPL(phytium_spi_check_status); @@ -243,7 +241,9 @@ static int phytium_spi_transfer_one(struct spi_master *master, if (transfer->speed_hz != fts->current_freq) { if (transfer->speed_hz != chip->speed_hz) { - clk_div = (fts->max_freq / transfer->speed_hz + 1) & 0xfffe; + clk_div = (fts->max_freq / transfer->speed_hz + 1) & + 0xfffe; + chip->speed_hz = transfer->speed_hz; chip->clk_div = clk_div; } @@ -275,19 +275,21 @@ static int phytium_spi_transfer_one(struct spi_master *master, cr0 |= (chip->tmode << TMOD_OFFSET); } - phytium_writel(fts, CTRL0, cr0); + phytium_writel(fts, CTRLR0, cr0); + /* check if current transfer is a DMA transcation */ if (master->can_dma && master->can_dma(master, spi, transfer)) fts->dma_mapped = master->cur_msg_mapped; spi_mask_intr(fts, 0xff); + /* DMA setup */ if (fts->dma_mapped) { ret = fts->dma_ops->dma_setup(fts, transfer); if (ret) return ret; } - + /* interrupt transfer mode setup */ if (!chip->poll_mode && !fts->dma_mapped) { txlevel = min_t(u16, fts->fifo_len / 2, fts->len / fts->n_bytes); phytium_writel(fts, TXFLTR, txlevel); @@ -354,7 +356,7 @@ static int phytium_spi_setup(struct spi_device *spi) cr0 = (spi->bits_per_word - 1) | (chip->type << FRF_OFFSET) | (spi->mode << MODE_OFFSET) | (chip->tmode << TMOD_OFFSET); - phytium_writel(fts, CTRL0, cr0); + phytium_writel(fts, CTRLR0, cr0); spi_enable_chip(fts, 1); @@ -460,7 +462,6 @@ void phytium_spi_remove_host(struct phytium_spi *fts) { if (fts->dma_ops && fts->dma_ops->dma_exit) fts->dma_ops->dma_exit(fts); - spi_shutdown_chip(fts); spi_unregister_controller(fts->master); diff --git a/drivers/spi/spi-phytium.h b/drivers/spi/spi-phytium.h index f1f234b5952..781a4fae52d 100644 --- a/drivers/spi/spi-phytium.h +++ b/drivers/spi/spi-phytium.h @@ -11,7 +11,7 @@ #include #include -#define CTRL0 0x00 +#define CTRLR0 0x00 #define SSIENR 0x08 #define SER 0x10 #define BAUDR 0x14 @@ -42,7 +42,6 @@ #define INT_TXOI (1 << 1) #define INT_RXUI (1 << 2) #define INT_RXOI (1 << 3) - /* Bit fields in SR, 7 bits */ #define SR_MASK 0x7f /* cover 7 bits */ #define SR_BUSY (1 << 0) @@ -52,15 +51,11 @@ #define SR_RF_FULL (1 << 4) #define SR_TX_ERR (1 << 5) #define SR_DCOL (1 << 6) - /* Bit fields in DMACR */ #define SPI_DMA_RDMAE (1 << 0) #define SPI_DMA_TDMAE (1 << 1) - #define SPI_WAIT_RETRIES 5 - struct phytium_spi; - struct phytium_spi_dma_ops { int (*dma_init)(struct device *dev, struct phytium_spi *fts); void (*dma_exit)(struct phytium_spi *fts); @@ -95,9 +90,8 @@ struct phytium_spi { void *rx_end; u8 n_bytes; int dma_mapped; - struct clk *clk; irqreturn_t (*transfer_handler)(struct phytium_spi *fts); - + /* DMA info */ u32 current_freq; /* frequency in hz */ struct dma_chan *txchan; u32 txburst; @@ -105,7 +99,7 @@ struct phytium_spi { u32 rxburst; u32 dma_sg_burst; unsigned long dma_chan_busy; - dma_addr_t dma_addr; + dma_addr_t dma_addr; /* phy address of the Data register */ const struct phytium_spi_dma_ops *dma_ops; struct completion dma_completion; }; @@ -114,22 +108,18 @@ static inline u32 phytium_readl(struct phytium_spi *fts, u32 offset) { return __raw_readl(fts->regs + offset); } - static inline u16 phytium_readw(struct phytium_spi *fts, u32 offset) { return __raw_readw(fts->regs + offset); } - static inline void phytium_writel(struct phytium_spi *fts, u32 offset, u32 val) { __raw_writel(val, fts->regs + offset); } - static inline void phytium_writew(struct phytium_spi *fts, u32 offset, u16 val) { __raw_writew(val, fts->regs + offset); } - static inline u32 phytium_read_io_reg(struct phytium_spi *fts, u32 offset) { switch (fts->reg_io_width) { @@ -140,8 +130,8 @@ static inline u32 phytium_read_io_reg(struct phytium_spi *fts, u32 offset) return phytium_readl(fts, offset); } } - -static inline void phytium_write_io_reg(struct phytium_spi *fts, u32 offset, u32 val) +static inline void phytium_write_io_reg(struct phytium_spi *fts, + u32 offset, u32 val) { switch (fts->reg_io_width) { case 2: @@ -153,17 +143,14 @@ static inline void phytium_write_io_reg(struct phytium_spi *fts, u32 offset, u32 break; } } - static inline void spi_enable_chip(struct phytium_spi *fts, int enable) { phytium_writel(fts, SSIENR, (enable ? 1 : 0)); } - static inline void spi_set_clk(struct phytium_spi *fts, u16 div) { phytium_writel(fts, BAUDR, div); } - static inline void spi_mask_intr(struct phytium_spi *fts, u32 mask) { u32 new_mask; @@ -171,7 +158,6 @@ static inline void spi_mask_intr(struct phytium_spi *fts, u32 mask) new_mask = phytium_readl(fts, IMR) & ~mask; phytium_writel(fts, IMR, new_mask); } - static inline void spi_umask_intr(struct phytium_spi *fts, u32 mask) { u32 new_mask; @@ -179,17 +165,15 @@ static inline void spi_umask_intr(struct phytium_spi *fts, u32 mask) new_mask = phytium_readl(fts, IMR) | mask; phytium_writel(fts, IMR, new_mask); } - static inline void spi_global_cs(struct phytium_spi *fts) { u32 global_cs_en, mask, setmask; mask = GENMASK(fts->num_cs-1, 0) << fts->num_cs; setmask = ~GENMASK(fts->num_cs-1, 0); - global_cs_en = (phytium_readl(fts, GCSR) | mask) & setmask; + global_cs_en = (phytium_readl(fts, GCSR) | mask) & setmask; phytium_writel(fts, GCSR, global_cs_en); } - static inline void spi_reset_chip(struct phytium_spi *fts) { spi_enable_chip(fts, 0); @@ -198,19 +182,16 @@ static inline void spi_reset_chip(struct phytium_spi *fts) spi_mask_intr(fts, 0xff); spi_enable_chip(fts, 1); } - static inline void spi_shutdown_chip(struct phytium_spi *fts) { spi_enable_chip(fts, 0); spi_set_clk(fts, 0); fts->current_freq = 0; } - extern int phytium_spi_add_host(struct device *dev, struct phytium_spi *fts); extern void phytium_spi_remove_host(struct phytium_spi *fts); extern int phytium_spi_suspend_host(struct phytium_spi *fts); extern int phytium_spi_resume_host(struct phytium_spi *fts); extern void phytium_spi_dmaops_set(struct phytium_spi *fts); extern int phytium_spi_check_status(struct phytium_spi *fts, bool raw); - #endif /* PHYTIUM_SPI_HEADER_H */ -- Gitee From d181ddeab34c666f9085115cdb40867e4e11cac7 Mon Sep 17 00:00:00 2001 From: Li Wencheng Date: Mon, 25 Mar 2024 17:38:27 +0800 Subject: [PATCH 22/71] net/stmmac: Add phytium DWMAC driver support v2 Modify stmmmac driver to support phytium DWMAC controler. Signed-off-by: Li Wencheng Signed-off-by: Chen Baozi Signed-off-by: Wang Yinfeng Change-Id: I878377c5fb88935dcbc7b83f368ae5408938f890 --- MAINTAINERS | 1 + .../ethernet/stmicro/stmmac/dwmac-phytium.c | 37 ++++++++----------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index dbf220d4f51..d492a084d59 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17469,6 +17469,7 @@ F: drivers/mmc/host/phytium-mci* F: drivers/mmc/host/phytium-sdci.* F: drivers/mtd/nand/raw/phytium_nand* F: drivers/net/can/phytium/* +F: drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c F: drivers/pci/controller/pcie-phytium* F: drivers/pwm/pwm-phytium.c F: drivers/spi/spi-phytium* diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c index a930cea6280..d31b8e870f6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c @@ -37,8 +37,7 @@ static int phytium_get_mac_mode(struct fwnode_handle *fwnode) static int phytium_dwmac_acpi_phy(struct plat_stmmacenet_data *plat, struct fwnode_handle *np, struct device *dev) { - plat->mdio_bus_data = - devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); + plat->mdio_bus_data = devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); if (!plat->mdio_bus_data) return -ENOMEM; @@ -60,8 +59,7 @@ static int phytium_dwmac_probe(struct platform_device *pdev) if (!plat) return -ENOMEM; - plat->dma_cfg = - devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL); + plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL); if (!plat->dma_cfg) return -ENOMEM; @@ -113,12 +111,10 @@ static int phytium_dwmac_probe(struct platform_device *pdev) &plat->unicast_filter_entries)) plat->unicast_filter_entries = 1; - if (fwnode_property_read_u32(fwnode, "tx-fifo-depth", - &plat->tx_fifo_size)) + if (fwnode_property_read_u32(fwnode, "tx-fifo-depth", &plat->tx_fifo_size)) plat->tx_fifo_size = 0x1000; - if (fwnode_property_read_u32(fwnode, "rx-fifo-depth", - &plat->rx_fifo_size)) + if (fwnode_property_read_u32(fwnode, "rx-fifo-depth", &plat->rx_fifo_size)) plat->rx_fifo_size = 0x1000; if (phytium_dwmac_acpi_phy(plat, fwnode, &pdev->dev)) @@ -133,11 +129,9 @@ static int phytium_dwmac_probe(struct platform_device *pdev) clk_freq = 125000000; /* Set system clock */ - snprintf(clk_name, sizeof(clk_name), "%s-%d", "stmmaceth", - plat->bus_id); + snprintf(clk_name, sizeof(clk_name), "%s-%d", "stmmaceth", plat->bus_id); - plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev, clk_name, NULL, - 0, clk_freq); + plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev, clk_name, NULL, 0, clk_freq); if (IS_ERR(plat->stmmac_clk)) { dev_warn(&pdev->dev, "Fail to register stmmac-clk\n"); plat->stmmac_clk = NULL; @@ -158,13 +152,10 @@ static int phytium_dwmac_probe(struct platform_device *pdev) fwnode_property_read_u32(fwnode, "snps,txpbl", &plat->dma_cfg->txpbl); fwnode_property_read_u32(fwnode, "snps,rxpbl", &plat->dma_cfg->rxpbl); - plat->dma_cfg->pblx8 = - !fwnode_property_read_bool(fwnode, "snps,no-pbl-x8"); + plat->dma_cfg->pblx8 = !fwnode_property_read_bool(fwnode, "snps,no-pbl-x8"); plat->dma_cfg->aal = fwnode_property_read_bool(fwnode, "snps,aal"); - plat->dma_cfg->fixed_burst = - fwnode_property_read_bool(fwnode, "snps,fixed-burst"); - plat->dma_cfg->mixed_burst = - fwnode_property_read_bool(fwnode, "snps,mixed-burst"); + plat->dma_cfg->fixed_burst = fwnode_property_read_bool(fwnode, "snps,fixed-burst"); + plat->dma_cfg->mixed_burst = fwnode_property_read_bool(fwnode, "snps,mixed-burst"); plat->axi->axi_lpi_en = false; plat->axi->axi_xit_frm = false; @@ -182,10 +173,10 @@ static int phytium_dwmac_probe(struct platform_device *pdev) stmmac_res.wol_irq = stmmac_res.irq; stmmac_res.lpi_irq = -1; - return stmmac_dvr_probe(&pdev->dev, plat, &stmmac_res); + return stmmac_dvr_probe(&pdev->dev, plat, &stmmac_res); } -void phytium_dwmac_remove(struct platform_device *pdev) +int phytium_dwmac_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(ndev); @@ -193,12 +184,14 @@ void phytium_dwmac_remove(struct platform_device *pdev) stmmac_pltfr_remove(pdev); clk_unregister_fixed_rate(plat->stmmac_clk); + + return 0; } #ifdef CONFIG_OF static const struct of_device_id phytium_dwmac_of_match[] = { { .compatible = "phytium,gmac" }, - {} + { } }; MODULE_DEVICE_TABLE(of, phytium_dwmac_of_match); #endif @@ -213,7 +206,7 @@ MODULE_DEVICE_TABLE(acpi, phytium_dwmac_acpi_ids); static struct platform_driver phytium_dwmac_driver = { .probe = phytium_dwmac_probe, - .remove_new = phytium_dwmac_remove, + .remove = phytium_dwmac_remove, .driver = { .name = "phytium-dwmac", .of_match_table = of_match_ptr(phytium_dwmac_of_match), -- Gitee From 18a117c8a48ad9c4d136230b0b7094d4ac1a166e Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Fri, 10 May 2024 14:44:27 +0800 Subject: [PATCH 23/71] codecs: es8336: update to 6.6.0.1 base version Signed-off-by: liutianyu1250 --- sound/soc/codecs/es8336.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/es8336.c b/sound/soc/codecs/es8336.c index dfdb5bf7025..907396fd439 100644 --- a/sound/soc/codecs/es8336.c +++ b/sound/soc/codecs/es8336.c @@ -71,7 +71,7 @@ struct es8336_priv { struct gpio_desc *hp_det_gpio; bool muted; bool hp_inserted; - + bool spk_active_level; u8 mic_src; int pwr_count; }; @@ -90,7 +90,9 @@ static int es8336_reset(struct snd_soc_component *component) static void es8336_enable_spk(struct es8336_priv *es8336, bool enable) { - gpiod_set_value(es8336->spk_ctl_gpio, enable); + bool level; + level = enable ? es8336->spk_active_level : !es8336->spk_active_level; + gpiod_set_value(es8336->spk_ctl_gpio, level); } static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9600, 50, 1); @@ -979,8 +981,10 @@ static int es8336_i2c_probe(struct i2c_client *i2c) if (IS_ERR_OR_NULL(es8336->spk_ctl_gpio)) dev_info(&i2c->dev, "Can not get spk_ctl_gpio\n"); - else + else { + es8336->spk_active_level = 0; es8336_enable_spk(es8336, false); + } es8336->hp_det_gpio = devm_gpiod_get_index_optional(&i2c->dev, "det", 0, GPIOD_IN); -- Gitee From c4e9b0029de0188d9555ce68693eb19cf390ad33 Mon Sep 17 00:00:00 2001 From: Zhou Zheng Date: Mon, 25 Mar 2024 19:22:49 +0800 Subject: [PATCH 24/71] codec: Phytium: Handle mute of different directions Without this patch,ADC mute will be called instead of DAC mute when recording ends. So,this patch correctly handles mute of ADC and DAC. Playbacking ends --- DAC mute. Recording ends --- ADC mute. Signed-off-by: Zhou Zheng Signed-off-by: Wang Yinfeng Change-Id: I0affc05e6d16aa557664950d0e8ad3e8c2506348 --- sound/soc/codecs/es8336.c | 22 ++++++++++++---------- sound/soc/codecs/es8388.c | 11 ++++++++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/es8336.c b/sound/soc/codecs/es8336.c index 907396fd439..159e34708ce 100644 --- a/sound/soc/codecs/es8336.c +++ b/sound/soc/codecs/es8336.c @@ -30,6 +30,7 @@ #include #include #include "es8336.h" +#define ES8336_MUTE (1 << 5) static struct snd_soc_component *es8336_component; @@ -668,17 +669,18 @@ static int es8336_mute(struct snd_soc_dai *dai, int mute, int direction) struct es8336_priv *es8336 = snd_soc_component_get_drvdata(component); es8336->muted = mute; - if (mute) { + if (!es8336->hp_inserted) + es8336_enable_spk(es8336, true); + else es8336_enable_spk(es8336, false); - msleep(100); - snd_soc_component_write(component, ES8336_DAC_SET1_REG30, 0x20); - } else if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK)) { - snd_soc_component_write(component, ES8336_DAC_SET1_REG30, 0x00); - msleep(130); - if (!es8336->hp_inserted) - es8336_enable_spk(es8336, true); - } - return 0; + if (direction) + return snd_soc_component_update_bits(dai->component, ES8336_ADC_MUTE_REG26, + ES8336_MUTE, + mute ? ES8336_MUTE : 0); + else + return snd_soc_component_update_bits(dai->component, ES8336_DAC_SET1_REG30, + ES8336_MUTE, + mute ? ES8336_MUTE : 0); } static int es8336_set_bias_level(struct snd_soc_component *component, diff --git a/sound/soc/codecs/es8388.c b/sound/soc/codecs/es8388.c index dd04993abe7..11959e97e61 100644 --- a/sound/soc/codecs/es8388.c +++ b/sound/soc/codecs/es8388.c @@ -421,9 +421,14 @@ static const struct snd_soc_dapm_route es8388_dapm_routes[] = { static int es8388_mute(struct snd_soc_dai *dai, int mute, int direction) { - return snd_soc_component_update_bits(dai->component, ES8388_DACCONTROL3, - ES8388_DACCONTROL3_DACMUTE, - mute ? ES8388_DACCONTROL3_DACMUTE : 0); + if (direction) + return snd_soc_component_update_bits(dai->component, ES8388_ADCCONTROL7, + ES8388_ADCCONTROL7_ADC_MUTE, + mute ? ES8388_ADCCONTROL7_ADC_MUTE : 0); + else + return snd_soc_component_update_bits(dai->component, ES8388_DACCONTROL3, + ES8388_DACCONTROL3_DACMUTE, + mute ? ES8388_DACCONTROL3_DACMUTE : 0); } static int es8388_startup(struct snd_pcm_substream *substream, -- Gitee From 051ad10a20189bc2fa37f2ac5527b11a6ea19105 Mon Sep 17 00:00:00 2001 From: Zhou Zheng Date: Mon, 25 Mar 2024 19:26:16 +0800 Subject: [PATCH 25/71] codec: Phytium: This patch makes ES8336 module reload smoothly It solves the problem of accessing NULL pointer when reloaded. Signed-off-by: Zhou Zheng Signed-off-by: Wang Yinfeng Change-Id: Ibfa62e4b42525bf18cdec0e086402de4a4a90946 --- sound/soc/codecs/es8336.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8336.c b/sound/soc/codecs/es8336.c index 159e34708ce..52bb3752ded 100644 --- a/sound/soc/codecs/es8336.c +++ b/sound/soc/codecs/es8336.c @@ -1011,7 +1011,7 @@ static int es8336_i2c_probe(struct i2c_client *i2c) msecs_to_jiffies(es8336->debounce_time)); } - ret = snd_soc_register_component(&i2c->dev, + ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_es8336, &es8336_dai, 1); @@ -1020,7 +1020,7 @@ static int es8336_i2c_probe(struct i2c_client *i2c) static void es8336_i2c_remove(struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + } static void es8336_i2c_shutdown(struct i2c_client *client) -- Gitee From 53d25d2880f205d3dd00204115103fb89bc54c5c Mon Sep 17 00:00:00 2001 From: Zhou Zheng Date: Mon, 25 Mar 2024 19:29:42 +0800 Subject: [PATCH 26/71] codec: Phytium: Ensure to use appropriate level to enable the SPK Speaker has two enabling ways(high or low level), so it add operation of reading the device tree property. Ensure to use appropriate level to enable the speaker. Add a variable to acquire the spk-active-level and change enabling relationship of hp_inserted. Signed-off-by: Zhou Zheng Signed-off-by: Wang Yinfeng Change-Id: Ib0f46ef06315103b96a60501abc5cdc401de4977 --- sound/soc/codecs/es8336.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/es8336.c b/sound/soc/codecs/es8336.c index 52bb3752ded..2d666ab2831 100644 --- a/sound/soc/codecs/es8336.c +++ b/sound/soc/codecs/es8336.c @@ -953,6 +953,7 @@ static int es8336_i2c_probe(struct i2c_client *i2c) struct es8336_priv *es8336; int ret = -1; int hp_irq; + int active_level = 0; es8336 = devm_kzalloc(&i2c->dev, sizeof(*es8336), GFP_KERNEL); if (!es8336) @@ -974,6 +975,7 @@ static int es8336_i2c_probe(struct i2c_client *i2c) es8336->spk_ctl_gpio = devm_gpiod_get_index_optional(&i2c->dev, "sel", 0, GPIOD_OUT_HIGH); + device_property_read_u32(&i2c->dev, "spk-active-level", &active_level); ret = of_property_read_u8(i2c->dev.of_node, "mic-src", &es8336->mic_src); if (ret != 0) { dev_dbg(&i2c->dev, "mic1-src return %d", ret); @@ -984,7 +986,7 @@ static int es8336_i2c_probe(struct i2c_client *i2c) if (IS_ERR_OR_NULL(es8336->spk_ctl_gpio)) dev_info(&i2c->dev, "Can not get spk_ctl_gpio\n"); else { - es8336->spk_active_level = 0; + es8336->spk_active_level = active_level; es8336_enable_spk(es8336, false); } -- Gitee From 96a83bdf60cd5a0de4aa3a208224912595f0d407 Mon Sep 17 00:00:00 2001 From: Zhou Zheng Date: Mon, 25 Mar 2024 19:34:25 +0800 Subject: [PATCH 27/71] i2s: phytium: Add clock divider in S3 resume Bugfix the problem that the sound is not played correctly after waking up from sleep. Signed-off-by: Zhou Zheng Signed-off-by: Wang Yinfeng Change-Id: Iae6a60dd6e85a43881898aab99d17e323376d65f --- sound/soc/phytium/local.h | 2 +- sound/soc/phytium/phytium_i2s.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/phytium/local.h b/sound/soc/phytium/local.h index 3967fe6a97a..8cc80d1d104 100644 --- a/sound/soc/phytium/local.h +++ b/sound/soc/phytium/local.h @@ -306,7 +306,7 @@ struct i2s_phytium { u32 xfer_resolution; u32 ccr; u32 clk_base; - + u32 cfg; struct i2s_clk_config_data config; /*azx_dev*/ diff --git a/sound/soc/phytium/phytium_i2s.c b/sound/soc/phytium/phytium_i2s.c index bee85fc0074..d84122f8efb 100644 --- a/sound/soc/phytium/phytium_i2s.c +++ b/sound/soc/phytium/phytium_i2s.c @@ -270,6 +270,7 @@ static int phytium_i2s_hw_params(struct snd_pcm_substream *substream, i2s_write_reg(dev->regs, CLK_CFG0, cfg); i2s_write_reg(dev->regs, CLK_CFG1, 0xf); } + dev->cfg = cfg; return 0; } @@ -367,7 +368,8 @@ static int phytium_i2s_resume(struct snd_soc_component *component) if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) phytium_i2s_config(dev, SNDRV_PCM_STREAM_CAPTURE); } - + i2s_write_reg(dev->regs, CLK_CFG0, dev->cfg); + i2s_write_reg(dev->regs, CLK_CFG1, 0xf); return 0; } #else -- Gitee From 0f9a93bea28b2db46120d3bf3211472613488b7e Mon Sep 17 00:00:00 2001 From: Zhou Zheng Date: Mon, 25 Mar 2024 19:39:45 +0800 Subject: [PATCH 28/71] i2s: phytium: Support for 24bit and 32bit format According to dma controller requirement, configure the DMA length as 0 for 24bit and 32 bit audio format. Signed-off-by: Zhou Zheng Signed-off-by: Wang Yinfeng Change-Id: I26684f72148034aeafe7e7bb5ae9492aebf52d4f --- sound/soc/phytium/phytium_i2s.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/sound/soc/phytium/phytium_i2s.c b/sound/soc/phytium/phytium_i2s.c index d84122f8efb..3fa8b2acc6f 100644 --- a/sound/soc/phytium/phytium_i2s.c +++ b/sound/soc/phytium/phytium_i2s.c @@ -548,6 +548,25 @@ static int phytium_pcm_hw_params(struct snd_soc_component *component, azx_dev->core.period_bytes = 0; azx_dev->core.format_val = 0; + switch (params_format(hw_params)) { + case SNDRV_PCM_FORMAT_S16_LE: + azx_dev->core.format_val = 2; + break; + + case SNDRV_PCM_FORMAT_S24_LE: + azx_dev->core.format_val = 0; + break; + + case SNDRV_PCM_FORMAT_S32_LE: + azx_dev->core.format_val = 0; + break; + + default: + dev_err(dev->dev, "phytium-i2s: unsupported PCM fmt"); + return -EINVAL; + } + + ret = chip->ops->substream_alloc_pages(chip, substream, params_buffer_bytes(hw_params)); @@ -683,11 +702,9 @@ int snd_i2s_stream_set_params(struct i2s_stream *azx_dev, period_bytes = snd_pcm_lib_period_bytes(substream); if (bufsize != azx_dev->bufsize || period_bytes != azx_dev->period_bytes || - format_val != azx_dev->format_val || runtime->no_period_wakeup != azx_dev->no_period_wakeup) { azx_dev->bufsize = bufsize; azx_dev->period_bytes = period_bytes; - azx_dev->format_val = format_val; azx_dev->no_period_wakeup = runtime->no_period_wakeup; err = snd_i2s_stream_setup_periods(azx_dev); if (err < 0) @@ -718,7 +735,7 @@ int snd_i2s_stream_setup(struct i2s_stream *azx_dev, int pcie, u32 paddr) i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), paddr + 0x1c8); i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(0), azx_dev->bufsize); i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(0), azx_dev->frags - 1); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(0), 0x2);//0x2 + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(0), azx_dev->format_val);//0x2 i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(0), 0x0);//0x0 } else { i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(1), (u32)azx_dev->bdl.addr); @@ -729,7 +746,7 @@ int snd_i2s_stream_setup(struct i2s_stream *azx_dev, int pcie, u32 paddr) i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), paddr + 0x1c0); i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(1), azx_dev->bufsize); i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(1), azx_dev->frags - 1); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(1), 0x8);//0x8 + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(1), azx_dev->format_val << 2);//0x8 i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(1), 0x0); } -- Gitee From 5f72d1351585125090392e8faaf97455cf65c85b Mon Sep 17 00:00:00 2001 From: Zhou Zheng Date: Mon, 25 Mar 2024 19:41:33 +0800 Subject: [PATCH 29/71] i2s: phytium: Exchange DMA channels According to design requirements, The DMA channel 0 must be used for recording, so exchange the DMA channels of recording and playback. Signed-off-by: Zhou Zheng Signed-off-by: Wang Yinfeng Change-Id: I01f3597d2b7534ae0bb4dda14d11fa48656ce518 --- sound/soc/phytium/phytium_i2s.c | 99 ++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/sound/soc/phytium/phytium_i2s.c b/sound/soc/phytium/phytium_i2s.c index 3fa8b2acc6f..0ac36260ce6 100644 --- a/sound/soc/phytium/phytium_i2s.c +++ b/sound/soc/phytium/phytium_i2s.c @@ -723,31 +723,31 @@ int snd_i2s_stream_setup(struct i2s_stream *azx_dev, int pcie, u32 paddr) else runtime = NULL; - i2s_write_reg(azx_dev->sd_addr, DMA_CHAL_CONFG0, 0x8180); + i2s_write_reg(azx_dev->sd_addr, DMA_CHAL_CONFG0, 0x8081); i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, 0x80000003); if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK) { - i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), (u32)azx_dev->bdl.addr); - i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), upper_32_bits(azx_dev->bdl.addr)); - if (pcie) - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), 0x1c8); - else - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), paddr + 0x1c8); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(0), azx_dev->bufsize); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(0), azx_dev->frags - 1); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(0), azx_dev->format_val);//0x2 - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(0), 0x0);//0x0 - } else { i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(1), (u32)azx_dev->bdl.addr); i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(1), upper_32_bits(azx_dev->bdl.addr)); if (pcie) - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), 0x1c0); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), 0x1c8); else - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), paddr + 0x1c0); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), paddr + 0x1c8); i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(1), azx_dev->bufsize); i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(1), azx_dev->frags - 1); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(1), azx_dev->format_val << 2);//0x8 - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(1), 0x0); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(1), azx_dev->format_val);//0x2 + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(1), 0x0);//0x0 + } else { + i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), (u32)azx_dev->bdl.addr); + i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), upper_32_bits(azx_dev->bdl.addr)); + if (pcie) + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), 0x1c0); + else + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), paddr + 0x1c0); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(0), azx_dev->bufsize); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(0), azx_dev->frags - 1); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(0), azx_dev->format_val << 2);//0x8 + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(0), 0x0); } if (runtime && runtime->period_size > 64) @@ -803,9 +803,9 @@ static int phytium_pcm_prepare(struct snd_soc_component *component, void snd_i2s_stream_clear(struct i2s_stream *azx_dev) { if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK) - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x0); - else i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0x0); + else + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x0); azx_dev->running = false; } @@ -818,9 +818,9 @@ void snd_i2s_stream_stop(struct i2s_stream *azx_dev) void snd_i2s_stream_start(struct i2s_stream *azx_dev, bool fresh_start) { if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK) - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x1); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0x1); else - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0x5); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x5); azx_dev->running = true; } @@ -889,19 +889,6 @@ void snd_i2s_stream_cleanup(struct i2s_stream *azx_dev) if (azx_dev->sd_addr) { if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK) { - mask = i2s_read_reg(azx_dev->sd_addr, DMA_MASK_INT); - mask &= ~BIT(0); - i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, mask); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0); - while (cnt--) { - if (i2s_read_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0)) == 0) - break; - } - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 2); - i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0); - i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), 0); - i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), 0); - } else { mask = i2s_read_reg(azx_dev->sd_addr, DMA_MASK_INT); mask &= ~BIT(1); i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, mask); @@ -914,6 +901,21 @@ void snd_i2s_stream_cleanup(struct i2s_stream *azx_dev) i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0); i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(1), 0); i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(1), 0); + i2s_write_reg(azx_dev->sd_addr, DMA_STS, azx_dev->sd_int_sta_mask); + } else { + mask = i2s_read_reg(azx_dev->sd_addr, DMA_MASK_INT); + mask &= ~BIT(0); + i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, mask); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0); + while (cnt--) { + if (i2s_read_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0)) == 0) + break; + } + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 2); + i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0); + i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), 0); + i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), 0); + i2s_write_reg(azx_dev->sd_addr, DMA_STS, azx_dev->sd_int_sta_mask); } } } @@ -943,9 +945,12 @@ static snd_pcm_uframes_t phytium_pcm_pointer(struct snd_soc_component *component { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct i2s_phytium *dev = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); - int stream = substream->stream; + u32 pos = 0; - u32 pos = i2s_read_reg(dev->regs_db, DMA_LPIB(stream)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + pos = i2s_read_reg(dev->regs_db, DMA_LPIB(1)); + else + pos = i2s_read_reg(dev->regs_db, DMA_LPIB(0)); return bytes_to_frames(substream->runtime, pos); } @@ -1107,9 +1112,9 @@ void snd_i2s_stream_init(struct i2sc_bus *bus, struct i2s_stream *stream, stream->sd_addr = bus->remap_addr; if (idx == 0) - stream->sd_int_sta_mask = 1 << idx; - else stream->sd_int_sta_mask = 1 << 8; + else + stream->sd_int_sta_mask = 1; stream->index = idx; stream->direction = direction; @@ -1395,27 +1400,29 @@ static int phytium_i2s_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_ACPI -static const struct acpi_device_id phytium_i2s_acpi_ids[] = { - { "PHYT0016", 0 }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(acpi, phytium_i2s_acpi_ids); -#endif - static const struct of_device_id phytium_i2s_of_match[] = { { .compatible = "phytium,i2s", }, {}, }; MODULE_DEVICE_TABLE(of, phytium_i2s_of_match); +#ifdef CONFIG_ACPI +static const struct acpi_device_id phytium_i2s_acpi_match[] = { + { "PHYT0016", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, phytium_i2s_acpi_ids); +#else +#define phytium_i2s_acpi_match NULL +#endif + static struct platform_driver phytium_i2s_driver = { .probe = phytium_i2s_probe, .remove = phytium_i2s_remove, .driver = { .name = "phytium-i2s", .of_match_table = of_match_ptr(phytium_i2s_of_match), - .acpi_match_table = ACPI_PTR(phytium_i2s_acpi_ids), + .acpi_match_table = phytium_i2s_acpi_match, }, }; -- Gitee From fe9b7ed8626db3421a7e8886cdd7b46080ed439b Mon Sep 17 00:00:00 2001 From: Dai Jingtao Date: Mon, 25 Mar 2024 18:05:54 +0800 Subject: [PATCH 30/71] hda: phytium: re-write function for dma_ops alloc This patch fix the problem when "dma-coherent" is described in DT on the board pd1904 and pd2008. The board pd2308 does not have the same problem. The old patch used API for ACPI when match dts node which may not meet the specification. This patch takes HDA node out of SOC node to avoid the influence of "dma-coherent". Signed-off-by: Dai Jingtao Signed-off-by: Wang Yinfeng Change-Id: Ia56576f2027187aed89c8acca66c88eb63067848 --- sound/pci/hda/hda_phytium.c | 44 +++++++++---------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/sound/pci/hda/hda_phytium.c b/sound/pci/hda/hda_phytium.c index dcf6c18def4..86cd17120b0 100644 --- a/sound/pci/hda/hda_phytium.c +++ b/sound/pci/hda/hda_phytium.c @@ -253,37 +253,6 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) return 1; /* OK, it's fine */ } -static int hda_ft_dma_configure(struct device *dev) -{ - const struct of_device_id *match_of; - const struct acpi_device_id *match_acpi; - - if (dev->of_node) { - match_of = of_match_device(dev->driver->of_match_table, dev); - if (!match_of) { - dev_err(dev, "Error DT match data is missing\n"); - return -ENODEV; - } - set_dma_ops(dev, NULL); - /* - * Because there is no way to transfer to non-coherent dma in - * of_dma_configure if 'dma-coherent' is described in DT, - * use acpi_dma_configure to alloc dma_ops correctly. - */ - acpi_dma_configure(dev, DEV_DMA_NON_COHERENT); - } else if (has_acpi_companion(dev)) { - match_acpi = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!match_acpi) { - dev_err(dev, "Error ACPI match data is missing\n"); - return -ENODEV; - } - set_dma_ops(dev, NULL); - acpi_dma_configure(dev, DEV_DMA_NON_COHERENT); - } - - return 0; -} - /* The work for pending PCM period updates. */ static void azx_irq_pending_work(struct work_struct *work) { @@ -840,6 +809,7 @@ static int azx_first_init(struct azx *chip) unsigned int dma_bits = 64; struct resource *res; + const struct acpi_device_id *match; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hda->regs = devm_ioremap_resource(hddev, res); @@ -876,9 +846,15 @@ static int azx_first_init(struct azx *chip) chip->align_buffer_size = 1; } - err = hda_ft_dma_configure(hddev); - if (err < 0) - return err; + if (has_acpi_companion(hddev)) { + match = acpi_match_device(hddev->driver->acpi_match_table, hddev); + if (!match) { + dev_err(hddev, "Error ACPI match data is missing\n"); + return -ENODEV; + } + set_dma_ops(hddev, NULL); + acpi_dma_configure(hddev, DEV_DMA_NON_COHERENT); + } /* allow 64bit DMA address if supported by H/W */ if (!(gcap & AZX_GCAP_64OK)) -- Gitee From 1075867e95b69a5159b58cfd92a4359671a10921 Mon Sep 17 00:00:00 2001 From: Dai Jingtao Date: Mon, 25 Mar 2024 21:08:53 +0800 Subject: [PATCH 31/71] dt-bindings:Phytium: Add binding for Dispaly controllor This patch documents the DT binding for the Phytium Display controller Signed-off-by: Dai Jingtao Signed-off-by: Yang Xun Signed-off-by: Wang Yinfeng Change-Id: I2681d4c956918fd8a9f03065da02e6345dd5295d --- .../devicetree/bindings/gpu/phytium,dc.yaml | 42 ++++++------------- MAINTAINERS | 1 + 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/Documentation/devicetree/bindings/gpu/phytium,dc.yaml b/Documentation/devicetree/bindings/gpu/phytium,dc.yaml index 5cea3a283fa..e5336599307 100644 --- a/Documentation/devicetree/bindings/gpu/phytium,dc.yaml +++ b/Documentation/devicetree/bindings/gpu/phytium,dc.yaml @@ -1,53 +1,35 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/gpu/phytium,dc.yaml# +$id: http://devicetree.org/schemas/sound/phytium,dc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Phytium Display Engine +title: Phytium Display Controller maintainers: - - Chen Baozi + - Dai Jingtao properties: compatible: - const: phytium,dc + enum: + - phytium,dc reg: - minItems: 1 - maxItems: 2 - description: | - Physical base address of the registers and length of memory mapped region, - and optional physical base address and length of reserved system memory. + items: + - description: DC registers interrupts: maxItems: 1 - pipe_mask: - $ref: '/schemas/types.yaml#/definitions/uint32' - description: specify which pipe is enabled, each bit corresponds to a pipe. - - edp_mask: - $ref: '/schemas/types.yaml#/definitions/uint32' - description: specify which pipe is edp port, each bit corresponds to a pipe (0:dp, 1:edp). - - required: - compatible - reg - interrupts - - pipe_mask - - edp_mask examples: - | - /memreserve/ 0xf4000000 0x4000000; // (optional) - - dc0@32000000 { - compatible = "phytium,dc"; - reg = <0x0 0x32000000 0x0 0x8000>, - <0x0 0xf4000000 0x0 0x4000000>; // (optional) - interrupts = ; - pipe_mask = 0x3; - edp_mask = 0x0; + dc@32000000 { + compatible = "phytium,dc"; + reg = <0x0 0x32000000 0x0 0x8000>; + interrupts = ; }; diff --git a/MAINTAINERS b/MAINTAINERS index d492a084d59..5a4dc4f7c1e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17423,6 +17423,7 @@ F: Documentation/devicetree/bindings/dma/phytium-ddma.yaml F: Documentation/devicetree/bindings/edac/phytium-pe220x-edac.txt F: Documentation/devicetree/bindings/gpio/phytium,gpio.yaml F: Documentation/devicetree/bindings/gpio/phytium,sgpio.yaml +F: Documentation/devicetree/bindings/gpu/phytium,dc.yaml F: drivers/hwmon/tacho-phytium.c F: Documentation/devicetree/bindings/hwlock/phytium,hwspinlock.yaml F: Documentation/devicetree/bindings/hwmon/phytium,tacho.yaml -- Gitee From 9cb8e798884d5fbba7075e214a3b33c66d37a025 Mon Sep 17 00:00:00 2001 From: Dai Jingtao Date: Mon, 25 Mar 2024 21:15:38 +0800 Subject: [PATCH 32/71] drm/phytium: Add Phytium Display Engine support v2 The Phytium chipset and subsequent SoCs share the same display controller with display ports. Add this driver to support it. Signed-off-by: Yang Xun Signed-off-by: Dai Jingtao Signed-off-by: Liu Tao Signed-off-by: Chen Baozi Signed-off-by: Wang Yinfeng Change-Id: I577763ff2de841df8ec4aa32cba63ed6b070c866 Signed-off-by: liutianyu1250 --- MAINTAINERS | 1 + drivers/gpu/drm/phytium/Kconfig | 5 +++-- drivers/gpu/drm/phytium/Makefile | 2 -- drivers/gpu/drm/phytium/phytium_crtc.c | 4 ++-- drivers/gpu/drm/phytium/phytium_display_drv.c | 4 ++-- drivers/gpu/drm/phytium/phytium_dp.c | 4 ++-- drivers/gpu/drm/phytium/phytium_fbdev.c | 13 +++++++++++-- drivers/gpu/drm/phytium/phytium_gem.c | 12 ++---------- drivers/gpu/drm/phytium/phytium_gem.h | 1 - 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5a4dc4f7c1e..24b491bfa51 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17456,6 +17456,7 @@ F: drivers/dma/phytium/phytium-ddmac.c F: drivers/edac/phytium_edac.c F: drivers/gpio/gpio-phytium* F: drivers/gpio/gpio-phytium-sgpio.c +F: drivers/gpu/drm/phytium/* F: drivers/hwspinlock/phytium_hwspinlock.c F: drivers/i2c/busses/i2c-phytium-* F: drivers/iio/adc/phytium-adc.c diff --git a/drivers/gpu/drm/phytium/Kconfig b/drivers/gpu/drm/phytium/Kconfig index 46297c1baad..d0b4577f17f 100644 --- a/drivers/gpu/drm/phytium/Kconfig +++ b/drivers/gpu/drm/phytium/Kconfig @@ -1,9 +1,10 @@ -# SPDX-License-Identifier: GPL-2.0-only - config DRM_PHYTIUM tristate "DRM Support for Phytium Graphics Card" depends on DRM select DRM_KMS_HELPER + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HDCP_HELPER help Choose this option if you have a phytium graphics card. This driver provides kernel mode setting and buffer management to userspace. diff --git a/drivers/gpu/drm/phytium/Makefile b/drivers/gpu/drm/phytium/Makefile index 1f68cdcd80d..2dc7ea1118c 100644 --- a/drivers/gpu/drm/phytium/Makefile +++ b/drivers/gpu/drm/phytium/Makefile @@ -1,5 +1,3 @@ -# SPDX-License-Identifier: GPL-2.0-only - phytium-dc-drm-y := phytium_display_drv.o \ phytium_plane.o \ phytium_crtc.o \ diff --git a/drivers/gpu/drm/phytium/phytium_crtc.c b/drivers/gpu/drm/phytium/phytium_crtc.c index e41c09c0b9c..8adc1c6e10d 100644 --- a/drivers/gpu/drm/phytium/phytium_crtc.c +++ b/drivers/gpu/drm/phytium/phytium_crtc.c @@ -29,8 +29,8 @@ #define MATH_Add(X, Y) ((float)((X) + (Y))) #define MATH_Multiply(X, Y) ((float)((X) * (Y))) #define MATH_Divide(X, Y) ((float)((X) / (Y))) -#define MATH_DivideFromUInteger(X, Y) (((float)(X) / (float)(Y))) -#define MATH_I2Float(X) ((float)(X)) +#define MATH_DivideFromUInteger(X, Y) ((float)(X) / (float)(Y)) +#define MATH_I2Float(X) ((float)(X)) struct filter_blit_array { uint8_t kernelSize; diff --git a/drivers/gpu/drm/phytium/phytium_display_drv.c b/drivers/gpu/drm/phytium/phytium_display_drv.c index 4c2287b3373..3203f606e19 100644 --- a/drivers/gpu/drm/phytium/phytium_display_drv.c +++ b/drivers/gpu/drm/phytium/phytium_display_drv.c @@ -253,8 +253,8 @@ static int phytium_display_load(struct drm_device *dev, unsigned long flags) priv->vram_hw_init(priv); phytium_irq_preinstall(dev); - ret = request_irq(priv->irq, phytium_display_irq_handler, - IRQF_SHARED, dev->driver->name, dev); + ret = request_irq(priv->irq, phytium_display_irq_handler, IRQF_SHARED, + dev->driver->name, dev); if (ret) { DRM_ERROR("install irq failed\n"); goto failed_irq_install; diff --git a/drivers/gpu/drm/phytium/phytium_dp.c b/drivers/gpu/drm/phytium/phytium_dp.c index 40583f28d82..6f84743215e 100644 --- a/drivers/gpu/drm/phytium/phytium_dp.c +++ b/drivers/gpu/drm/phytium/phytium_dp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -299,7 +300,7 @@ static int phytium_connector_add_common_modes(struct phytium_dp_device *phytium_ mode->hdisplay = common_mode[i].w; mode->vdisplay = common_mode[i].h; mode->type &= ~DRM_MODE_TYPE_PREFERRED; - strncpy(mode->name, common_mode[i].name, DRM_DISPLAY_MODE_LEN); + strscpy(mode->name, common_mode[i].name, DRM_DISPLAY_MODE_LEN); drm_mode_probed_add(&phytium_dp->connector, mode); ret++; } @@ -1105,7 +1106,6 @@ static int phytium_dp_dpcd_set_link(struct phytium_dp_device *phytium_dp, link_config[1] = lane_count; if (drm_dp_enhanced_frame_cap(phytium_dp->dpcd)) link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - ret = drm_dp_dpcd_write(&phytium_dp->aux, DP_LINK_BW_SET, link_config, 2); if (ret < 0) { DRM_NOTE("write dpcd DP_LINK_BW_SET fail: ret:%d\n", ret); diff --git a/drivers/gpu/drm/phytium/phytium_fbdev.c b/drivers/gpu/drm/phytium/phytium_fbdev.c index a3cbe234902..adce24d159b 100644 --- a/drivers/gpu/drm/phytium/phytium_fbdev.c +++ b/drivers/gpu/drm/phytium/phytium_fbdev.c @@ -16,6 +16,14 @@ #define PHYTIUM_MAX_CONNECTOR 1 #define helper_to_drm_private(x) container_of(x, struct phytium_display_private, fbdev_helper) +static void phytium_fbdev_destroy(struct fb_info *info) +{ + struct drm_fb_helper *helper = info->par; + struct phytium_display_private *priv = helper_to_drm_private(helper); + + phytium_gem_free_object(&priv->fbdev_phytium_gem->base); +} + static int phytium_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct drm_fb_helper *helper = info->par; @@ -26,9 +34,10 @@ static int phytium_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) static const struct fb_ops phytium_fbdev_ops = { .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, .fb_mmap = phytium_fbdev_mmap, - __FB_DEFAULT_DMAMEM_OPS_DRAW, + .fb_destroy = phytium_fbdev_destroy, + DRM_FB_HELPER_DEFAULT_OPS, + FB_DEFAULT_IOMEM_OPS, }; static int diff --git a/drivers/gpu/drm/phytium/phytium_gem.c b/drivers/gpu/drm/phytium/phytium_gem.c index c4d2c844c14..616fddf2070 100644 --- a/drivers/gpu/drm/phytium/phytium_gem.c +++ b/drivers/gpu/drm/phytium/phytium_gem.c @@ -172,12 +172,6 @@ void phytium_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map) int phytium_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { - int ret = 0; - - ret = drm_gem_mmap_obj(obj, obj->size, vma); - if (ret < 0) - return ret; - return phytium_gem_mmap_obj(obj, vma); } @@ -392,10 +386,7 @@ int phytium_gem_mmap(struct file *filp, struct vm_area_struct *vma) int ret = 0; ret = drm_gem_mmap(filp, vma); - if (ret < 0) - return ret; - - return phytium_gem_mmap_obj(vma->vm_private_data, vma); + return ret; } static const struct vm_operations_struct phytium_vm_ops = { @@ -409,6 +400,7 @@ static const struct drm_gem_object_funcs phytium_drm_gem_object_funcs = { .vmap = phytium_gem_prime_vmap, .vunmap = phytium_gem_prime_vunmap, .vm_ops = &phytium_vm_ops, + .mmap = phytium_gem_prime_mmap, }; struct phytium_gem_object *phytium_gem_create_object(struct drm_device *dev, unsigned long size) diff --git a/drivers/gpu/drm/phytium/phytium_gem.h b/drivers/gpu/drm/phytium/phytium_gem.h index eb6f8987a2b..693d5408fee 100644 --- a/drivers/gpu/drm/phytium/phytium_gem.h +++ b/drivers/gpu/drm/phytium/phytium_gem.h @@ -37,7 +37,6 @@ int phytium_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, unsi struct phytium_gem_object *phytium_gem_create_object(struct drm_device *dev, unsigned long size); int phytium_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); -int phytium_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); int phytium_gem_suspend(struct drm_device *drm_dev); void phytium_gem_resume(struct drm_device *drm_dev); #endif /* __PHYTIUM_GEM_H__ */ -- Gitee From 8365b49c4563c9085dc13927da667cfdba8c6f1f Mon Sep 17 00:00:00 2001 From: WangHao Date: Mon, 25 Mar 2024 13:23:30 +0000 Subject: [PATCH 33/71] drm/phytium: Add capability of tile mode Add the capability of tile mode for gpu requirements. Signed-off-by: WangHao Signed-off-by: Yang Xun Signed-off-by: Chen Baozi Signed-off-by: Wang Yinfeng Change-Id: If22ad9c5dbe46a95a69d65a95347558a516d639c --- drivers/gpu/drm/phytium/phytium_plane.c | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/phytium/phytium_plane.c b/drivers/gpu/drm/phytium/phytium_plane.c index 315ad6b4b81..bc28ad8d45c 100644 --- a/drivers/gpu/drm/phytium/phytium_plane.c +++ b/drivers/gpu/drm/phytium/phytium_plane.c @@ -108,6 +108,35 @@ phytium_plane_atomic_destroy_state(struct drm_plane *plane, struct drm_plane_sta kfree(phytium_state); } +static bool phytium_plane_format_mod_supported(struct drm_plane *plane, + uint32_t format, uint64_t modifier) +{ + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + + if (modifier == DRM_FORMAT_MOD_PHYTIUM_TILE_MODE3_FBCDC) { + switch (format) { + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRA1010102: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_RGBA8888: + case DRM_FORMAT_BGRA8888: + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_BGRX8888: + return true; + default: + return false; + } + } + + return false; +} + const struct drm_plane_funcs phytium_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -117,6 +146,7 @@ const struct drm_plane_funcs phytium_plane_funcs = { .atomic_set_property = phytium_plane_atomic_set_property, .atomic_duplicate_state = phytium_plane_atomic_duplicate_state, .atomic_destroy_state = phytium_plane_atomic_destroy_state, + .format_mod_supported = phytium_plane_format_mod_supported, }; static int -- Gitee From 82c03686bb21d17c2604bdfbba88a28330101cdb Mon Sep 17 00:00:00 2001 From: WangHao Date: Mon, 25 Mar 2024 13:25:50 +0000 Subject: [PATCH 34/71] drm/phytium: Get audio capability from EDID In order to handle the audio plugged event, get the audio capability from EDID. Signed-off-by: WangHao Signed-off-by: Yang Xun Signed-off-by: Chen Baozi Signed-off-by: Wang Yinfeng Change-Id: Ieb6347f4600f2c187a3e90b8eee59892eb346bc4 --- drivers/gpu/drm/phytium/phytium_dp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/phytium/phytium_dp.c b/drivers/gpu/drm/phytium/phytium_dp.c index 6f84743215e..567dfdc3d5e 100644 --- a/drivers/gpu/drm/phytium/phytium_dp.c +++ b/drivers/gpu/drm/phytium/phytium_dp.c @@ -1729,6 +1729,7 @@ static int phytium_dp_long_pulse(struct drm_connector *connector, bool hpd_raw_s enum drm_connector_status status = connector->status; bool video_enable = false; uint32_t index = 0; + struct edid *edid = NULL; if (phytium_dp->is_edp) status = connector_status_connected; @@ -1762,6 +1763,15 @@ static int phytium_dp_long_pulse(struct drm_connector *connector, bool hpd_raw_s mdelay(2); phytium_dp_hw_enable_video(phytium_dp); } + + edid = drm_get_edid(connector, &phytium_dp->aux.ddc); + + if (edid && drm_edid_is_valid(edid)) + phytium_dp->has_audio = drm_detect_monitor_audio(edid); + else + phytium_dp->has_audio = false; + + kfree(edid); } out: -- Gitee From b846c94f6c741db3d855b27b12588b1a24c976cc Mon Sep 17 00:00:00 2001 From: WangHao Date: Mon, 25 Mar 2024 13:28:14 +0000 Subject: [PATCH 35/71] drm/phytium: Bugfix Xorg startup for ps23xx when using pe2201 bmc card When the pe2201 bmc card is detected on ps23xx SoCs, map the card's graphics memory to device attributes to avoid unnecessary trouble. Signed-off-by: WangHao Signed-off-by: Yang Xun Signed-off-by: Wang Yinfeng Change-Id: I1b2ec2c4096ca0d5d89ad8042b1b6a0a1156601b --- drivers/gpu/drm/phytium/phytium_display_drv.c | 21 ++++++++++-- drivers/gpu/drm/phytium/phytium_display_drv.h | 3 +- drivers/gpu/drm/phytium/phytium_gem.c | 25 +++++++++----- drivers/gpu/drm/phytium/phytium_pci.c | 33 ++++++++++++++++--- 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/phytium/phytium_display_drv.c b/drivers/gpu/drm/phytium/phytium_display_drv.c index 3203f606e19..f94e0cf4ebe 100644 --- a/drivers/gpu/drm/phytium/phytium_display_drv.c +++ b/drivers/gpu/drm/phytium/phytium_display_drv.c @@ -249,7 +249,7 @@ static int phytium_display_load(struct drm_device *dev, unsigned long flags) goto failed_modeset_init; } - if (priv->support_memory_type & MEMORY_TYPE_VRAM) + if (priv->support_memory_type & (MEMORY_TYPE_VRAM_WC | MEMORY_TYPE_VRAM_DEVICE)) priv->vram_hw_init(priv); phytium_irq_preinstall(dev); @@ -285,8 +285,25 @@ static void phytium_display_unload(struct drm_device *dev) drm_mode_config_cleanup(dev); } +/* phytium display specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_PHYTIUM_VRAM_TYPE_DEVICE 0x0 +#define DRM_IOCTL_PHYTIUM_VRAM_TYPE_DEVICE DRM_IO(DRM_COMMAND_BASE\ + + DRM_PHYTIUM_VRAM_TYPE_DEVICE) + +static int phytium_ioctl_check_vram_device(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct phytium_display_private *priv = dev->dev_private; + + return ((priv->support_memory_type == MEMORY_TYPE_VRAM_DEVICE) ? 1 : 0); +} + static const struct drm_ioctl_desc phytium_ioctls[] = { /* for test, none so far */ + DRM_IOCTL_DEF_DRV(PHYTIUM_VRAM_TYPE_DEVICE, phytium_ioctl_check_vram_device, + DRM_AUTH|DRM_UNLOCKED), }; static const struct file_operations phytium_drm_driver_fops = { @@ -378,7 +395,7 @@ static int phytium_display_pm_resume(struct drm_device *dev) phytium_crtc_resume(dev); phytium_gem_resume(dev); - if (priv->support_memory_type & MEMORY_TYPE_VRAM) + if (priv->support_memory_type & (MEMORY_TYPE_VRAM_WC | MEMORY_TYPE_VRAM_DEVICE)) priv->vram_hw_init(priv); ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state); diff --git a/drivers/gpu/drm/phytium/phytium_display_drv.h b/drivers/gpu/drm/phytium/phytium_display_drv.h index 5aac502420d..d9d750eee30 100644 --- a/drivers/gpu/drm/phytium/phytium_display_drv.h +++ b/drivers/gpu/drm/phytium/phytium_display_drv.h @@ -49,9 +49,10 @@ enum phytium_mem_state_type { PHYTIUM_MEM_STATE_TYPE_COUNT, }; -#define MEMORY_TYPE_VRAM 0x1 +#define MEMORY_TYPE_VRAM_WC 0x1 #define MEMORY_TYPE_SYSTEM_CARVEOUT 0x2 #define MEMORY_TYPE_SYSTEM_UNIFIED 0x4 +#define MEMORY_TYPE_VRAM_DEVICE 0x8 #define IS_PLATFORM(priv, p) ((priv)->info.platform_mask & BIT(p)) diff --git a/drivers/gpu/drm/phytium/phytium_gem.c b/drivers/gpu/drm/phytium/phytium_gem.c index 616fddf2070..7d962076f7d 100644 --- a/drivers/gpu/drm/phytium/phytium_gem.c +++ b/drivers/gpu/drm/phytium/phytium_gem.c @@ -87,7 +87,8 @@ phytium_gem_prime_get_sg_table(struct drm_gem_object *obj) return ERR_PTR(-ENOMEM); } - if ((phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM) || + if ((phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_WC) || + (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_DEVICE) || (phytium_gem_obj->memory_type == MEMORY_TYPE_SYSTEM_CARVEOUT)) { ret = sg_alloc_table(sgt, 1, GFP_KERNEL); if (ret) { @@ -276,7 +277,8 @@ int phytium_gem_suspend(struct drm_device *drm_dev) int ret = 0; list_for_each_entry(phytium_gem_obj, &priv->gem_list_head, list) { - if (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM) + if ((phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_WC) && + (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_DEVICE)) continue; phytium_gem_obj->vaddr_save = vmalloc(phytium_gem_obj->size); @@ -295,7 +297,8 @@ int phytium_gem_suspend(struct drm_device *drm_dev) return 0; malloc_failed: list_for_each_entry(phytium_gem_obj, &priv->gem_list_head, list) { - if (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM) + if ((phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_WC) && + (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_DEVICE)) continue; if (phytium_gem_obj->vaddr_save) { @@ -312,7 +315,8 @@ void phytium_gem_resume(struct drm_device *drm_dev) struct phytium_gem_object *phytium_gem_obj = NULL; list_for_each_entry(phytium_gem_obj, &priv->gem_list_head, list) { - if (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM) + if ((phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_WC) && + (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_DEVICE)) continue; memcpy(phytium_gem_obj->vaddr, phytium_gem_obj->vaddr_save, phytium_gem_obj->size); @@ -331,7 +335,8 @@ void phytium_gem_free_object(struct drm_gem_object *obj) DRM_DEBUG_KMS("free phytium_gem_obj iova:0x%pa size:0x%lx\n", &phytium_gem_obj->iova, phytium_gem_obj->size); if (phytium_gem_obj->vaddr) { - if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM) { + if ((phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_WC) || + (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_DEVICE)) { phytium_memory_pool_free(priv, phytium_gem_obj->vaddr, size); priv->mem_state[PHYTIUM_MEM_VRAM_ALLOC] -= size; } else if (phytium_gem_obj->memory_type == MEMORY_TYPE_SYSTEM_CARVEOUT) { @@ -364,10 +369,14 @@ int phytium_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma) vma->vm_pgoff = 0; vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM) { + if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_WC) { vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ret = remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end - vma->vm_start, vma->vm_page_prot); + } else if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_DEVICE) { + vma->vm_page_prot = pgprot_device(vma->vm_page_prot); + ret = remap_pfn_range(vma, vma->vm_start, pfn, + vma->vm_end - vma->vm_start, vma->vm_page_prot); } else if (phytium_gem_obj->memory_type == MEMORY_TYPE_SYSTEM_CARVEOUT) { ret = remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end - vma->vm_start, vma->vm_page_prot); @@ -423,7 +432,7 @@ struct phytium_gem_object *phytium_gem_create_object(struct drm_device *dev, uns goto failed_object_init; } - if (priv->support_memory_type & MEMORY_TYPE_VRAM) { + if (priv->support_memory_type & (MEMORY_TYPE_VRAM_WC | MEMORY_TYPE_VRAM_DEVICE)) { ret = phytium_memory_pool_alloc(priv, &phytium_gem_obj->vaddr, &phytium_gem_obj->phys_addr, size); if (ret) { @@ -431,7 +440,7 @@ struct phytium_gem_object *phytium_gem_create_object(struct drm_device *dev, uns goto failed_dma_alloc; } phytium_gem_obj->iova = phytium_gem_obj->phys_addr; - phytium_gem_obj->memory_type = MEMORY_TYPE_VRAM; + phytium_gem_obj->memory_type = priv->support_memory_type; priv->mem_state[PHYTIUM_MEM_VRAM_ALLOC] += size; } else if (priv->support_memory_type & MEMORY_TYPE_SYSTEM_CARVEOUT) { ret = phytium_memory_pool_alloc(priv, &phytium_gem_obj->vaddr, diff --git a/drivers/gpu/drm/phytium/phytium_pci.c b/drivers/gpu/drm/phytium/phytium_pci.c index 114c6306fd1..3d91ad68a51 100644 --- a/drivers/gpu/drm/phytium/phytium_pci.c +++ b/drivers/gpu/drm/phytium/phytium_pci.c @@ -27,6 +27,24 @@ void phytium_pci_vram_hw_init(struct phytium_display_private *priv) pci_priv->dc_hw_vram_init(priv, priv->pool_phys_addr, priv->pool_size); } +static bool phytium_pci_host_is_5c01(struct pci_bus *bus) +{ + struct pci_bus *child = bus; + struct pci_dev *root = NULL; + + while (child) { + if (child->parent->parent) + child = child->parent; + else + break; + } + + root = child->self; + if ((root->vendor == 0x1db7) && (root->device == 0x5c01)) + return true; + return false; +} + int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private *priv) { int ret = 0; @@ -34,8 +52,15 @@ int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private * priv->pool_phys_addr = pci_resource_start(pdev, 2); priv->pool_size = pci_resource_len(pdev, 2); if ((priv->pool_phys_addr != 0) && (priv->pool_size != 0)) { - priv->pool_virt_addr = devm_ioremap_wc(&pdev->dev, priv->pool_phys_addr, - priv->pool_size); + if ((pdev->device == 0xdc3e) && phytium_pci_host_is_5c01(pdev->bus)) { + priv->pool_virt_addr = devm_ioremap(&pdev->dev, priv->pool_phys_addr, + priv->pool_size); + priv->support_memory_type = MEMORY_TYPE_VRAM_DEVICE; + } else { + priv->pool_virt_addr = devm_ioremap_wc(&pdev->dev, priv->pool_phys_addr, + priv->pool_size); + priv->support_memory_type = MEMORY_TYPE_VRAM_WC; + } if (priv->pool_virt_addr == NULL) { DRM_ERROR("pci vram ioremap fail, addr:0x%llx, size:0x%llx\n", priv->pool_phys_addr, priv->pool_size); @@ -47,7 +72,6 @@ int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private * goto failed_init_memory_pool; priv->mem_state[PHYTIUM_MEM_VRAM_TOTAL] = priv->pool_size; - priv->support_memory_type = MEMORY_TYPE_VRAM; priv->vram_hw_init = phytium_pci_vram_hw_init; } else { DRM_DEBUG_KMS("not support vram\n"); @@ -67,7 +91,8 @@ int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private * void phytium_pci_vram_fini(struct pci_dev *pdev, struct phytium_display_private *priv) { - if (priv->support_memory_type == MEMORY_TYPE_VRAM) { + if ((priv->support_memory_type == MEMORY_TYPE_VRAM_WC) || + (priv->support_memory_type == MEMORY_TYPE_VRAM_DEVICE)) { phytium_memory_pool_fini(&pdev->dev, priv); devm_iounmap(&pdev->dev, priv->pool_virt_addr); } -- Gitee From aade60326f6ca7cb62540aa6ff8ee1d1f98a488f Mon Sep 17 00:00:00 2001 From: WangHao Date: Mon, 25 Mar 2024 13:29:59 +0000 Subject: [PATCH 36/71] drm/phytium: Replace default efi fb0 with dc fb When enable efi fb, replace the original efi fb0 when loading the dc driver. Signed-off-by: WangHao Signed-off-by: Yang Xun Signed-off-by: Wang Yinfeng Change-Id: I0bcab6311402d38cbec0b430162351ccee1b57a1 --- drivers/gpu/drm/phytium/phytium_pci.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/phytium/phytium_pci.c b/drivers/gpu/drm/phytium/phytium_pci.c index 3d91ad68a51..e046c299da7 100644 --- a/drivers/gpu/drm/phytium/phytium_pci.c +++ b/drivers/gpu/drm/phytium/phytium_pci.c @@ -6,6 +6,7 @@ #include #include +#include #include #include "phytium_display_drv.h" #include "phytium_pci.h" @@ -238,12 +239,30 @@ phytium_pci_private_fini(struct pci_dev *pdev, struct phytium_display_private *p devm_kfree(&pdev->dev, pci_priv); } +static int phytium_remove_conflicting_framebuffers(struct pci_dev *pdev) +{ + resource_size_t base, size; + + base = pci_resource_start(pdev, 2); + size = pci_resource_len(pdev, 2); + + return drm_aperture_remove_conflicting_framebuffers(base, size, + &phytium_display_drm_driver); + +} + static int phytium_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct phytium_display_private *priv = NULL; struct drm_device *dev = NULL; int ret = 0; + ret = phytium_remove_conflicting_framebuffers(pdev); + if (ret) { + DRM_ERROR("failed to remove conflicting phytium framebuffers\n"); + return ret; + } + dev = drm_dev_alloc(&phytium_display_drm_driver, &pdev->dev); if (IS_ERR(dev)) { DRM_ERROR("failed to allocate drm_device\n"); -- Gitee From 5a3460ff24fdbae7a8c91cb8c38f800f940de186 Mon Sep 17 00:00:00 2001 From: YuDa Date: Mon, 25 Mar 2024 21:57:41 +0800 Subject: [PATCH 37/71] drm/phytium: Modify PHYTIUM_DP_INTERRUPT_MASK bit value Change the value of HPD_OTHER_MASK from 0x3c to 0x5c to mask the AUX reply error interrupt Signed-off-by: YuDa Signed-off-by: Yang Xun Signed-off-by: Wang Yinfeng Change-Id: I1c25d50c1a5661d4f938a3e8bfa6f8ca792e2145 --- drivers/gpu/drm/phytium/phytium_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/phytium/phytium_reg.h b/drivers/gpu/drm/phytium/phytium_reg.h index 4dca6c02312..20428a89b79 100644 --- a/drivers/gpu/drm/phytium/phytium_reg.h +++ b/drivers/gpu/drm/phytium/phytium_reg.h @@ -268,7 +268,7 @@ #define PHYTIUM_DP_INTERRUPT_MASK 0x0144 #define HPD_IRQ_MASK (1<<1) #define HPD_EVENT_MASK (1<<0) - #define HPD_OTHER_MASK 0x3c + #define HPD_OTHER_MASK 0x5c #define PHYTIUM_DP_AUX_REPLY_DATA_COUNT 0x0148 #define PHYTIUM_DP_AUX_STATUS 0x014C #define REPLY_RECEIVED 0x1 -- Gitee From eadfecf5347574d56849ab186779733a002f1ae4 Mon Sep 17 00:00:00 2001 From: Huang Jie Date: Tue, 19 Mar 2024 10:55:22 +0800 Subject: [PATCH 38/71] qspi: phytium: Resolved the problem that S3 hibernation causes flash modification and controller register clearing. S3 hibernation causes the flash to be modified and controller registers to be cleared. The wr_cfg register is cleared after programming communication is established between the controller and flash, and rd_cfg and flash_capacity registers upon wakes up. That would solve the problem. Signed-off-by: Huang Jie Signed-off-by: Peng Min Tested-by: Huang Jie Change-Id: Ie22ee02fc45089b2eee078b1747bd6709d4c470b --- drivers/spi/spi-phytium-qspi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-phytium-qspi.c b/drivers/spi/spi-phytium-qspi.c index fef637a140f..c68a790ed45 100644 --- a/drivers/spi/spi-phytium-qspi.c +++ b/drivers/spi/spi-phytium-qspi.c @@ -2,14 +2,13 @@ /* * Phytium Quad SPI controller driver. * - * Copyright (c) 2022-2024 Phytium Technology Co., Ltd. + * Copyright (c) 2022-2023, Phytium Technology Co., Ltd. */ #include #include #include #include -#include #include #include #include @@ -290,8 +289,6 @@ static void phytium_qspi_clear_wr(struct phytium_qspi *qspi, struct phytium_qspi_flash *flash) { u32 cmd = 0; - u32 state = 0; - int ret = 0; cmd |= 0x05 << QSPI_CMD_PORT_CMD_SHIFT; cmd |= BIT(QSPI_CMD_PORT_TRANSFER_SHIFT); @@ -300,13 +297,8 @@ static void phytium_qspi_clear_wr(struct phytium_qspi *qspi, writel_relaxed(cmd, qspi->io_base + QSPI_CMD_PORT_REG); readl_relaxed(qspi->io_base + QSPI_LD_PORT_REG); - ret = readl_poll_timeout(qspi->io_base + QSPI_LD_PORT_REG, - state, !(state & 0x01), 10, 100000); - if (ret) - dev_err(qspi->dev, "wait device timeout\n"); - /* clear wr_cfg */ - writel_relaxed(0x0, qspi->io_base + QSPI_WR_CFG_REG); + writel_relaxed(0, qspi->io_base + QSPI_WR_CFG_REG); } static int phytium_qspi_write_port(struct phytium_qspi *qspi, -- Gitee From 9518c70429f91de578b8b308dda764b57bc8d62f Mon Sep 17 00:00:00 2001 From: Huang Shaobo Date: Wed, 10 Apr 2024 09:07:40 +0800 Subject: [PATCH 39/71] S4: Phytium: Fix the wake-up failure after hibernation This patch fix the S4 hibernation wake-up failure.This issue stems from ARM's weak memory ordering, and current kernel lacks proper synchronization for compress data during hibernation on ARM. Signed-off-by: Huang Shaobo Signed-off-by: Wang Yinfeng Change-Id: Ib22c7158a5f34fdb214fa71819bd464b226be546 --- kernel/power/swap.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 74edbce2320..6f334bb43fa 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -662,6 +662,13 @@ static int lzo_compress_threadfn(void *data) d->ret = lzo1x_1_compress(d->unc, d->unc_len, d->cmp + LZO_HEADER, &d->cmp_len, d->wrk); +#ifdef CONFIG_ARM64 + /* + * Ensure that compressed data is indeed written to memory + * before atomic_set on weakly-ordered architectures. + */ + smp_wmb(); +#endif atomic_set(&d->stop, 1); wake_up(&d->done); } @@ -811,6 +818,10 @@ static int save_image_lzo(struct swap_map_handle *handle, for (run_threads = thr, thr = 0; thr < run_threads; thr++) { wait_event(data[thr].done, atomic_read(&data[thr].stop)); +#ifdef CONFIG_ARM64 + /* Force data access later than written */ + smp_rmb(); +#endif atomic_set(&data[thr].stop, 0); ret = data[thr].ret; -- Gitee From c40aae6239a7787aaa4cfc999d84c8c20aa28e92 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 9 May 2024 15:33:03 +0800 Subject: [PATCH 40/71] drm: phytium: fix build error Build error with such log: ... ERROR: modpost: "cfb_copyarea" [drivers/gpu/drm/phytium/phytium-dc-drm.ko] undefined! ERROR: modpost: "cfb_imageblit" [drivers/gpu/drm/phytium/phytium-dc-drm.ko] undefined! ERROR: modpost: "cfb_fillrect" [drivers/gpu/drm/phytium/phytium-dc-drm.ko] undefined! ... Add select FB_IOMEM_HELPERS in DRM_PHYTIUM Signed-off-by: liutianyu1250 --- drivers/gpu/drm/phytium/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/phytium/Kconfig b/drivers/gpu/drm/phytium/Kconfig index d0b4577f17f..e1b91e6a2ca 100644 --- a/drivers/gpu/drm/phytium/Kconfig +++ b/drivers/gpu/drm/phytium/Kconfig @@ -1,6 +1,7 @@ config DRM_PHYTIUM tristate "DRM Support for Phytium Graphics Card" depends on DRM + select FB_IOMEM_HELPERS select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_DISPLAY_DP_HELPER -- Gitee From 8dee31b5358967fdf1f7f5e9e30e4e67a5b20479 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 9 May 2024 16:28:39 +0800 Subject: [PATCH 41/71] edac: phytium: remove duplicate driver Signed-off-by: liutianyu1250 --- drivers/edac/Kconfig | 7 - drivers/edac/Makefile | 1 - drivers/edac/phytium_pe220x_edac.c | 480 ----------------------------- 3 files changed, 488 deletions(-) delete mode 100644 drivers/edac/phytium_pe220x_edac.c diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 69b71c803e6..1cbc7b48a04 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -568,11 +568,4 @@ config EDAC_NPCM error detection (in-line ECC in which a section 1/8th of the memory device used to store data is used for ECC storage). -config EDAC_PHYTIUM_PE220X - tristate "Phytium Pe220x SoC" - depends on ARCH_PHYTIUM - help - Support for error detection and correction on the - Phytium Pe220x family of SOCs. - endif # EDAC diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index d3caedd416b..f21c95254ab 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -87,4 +87,3 @@ obj-$(CONFIG_EDAC_BLUEFIELD) += bluefield_edac.o obj-$(CONFIG_EDAC_DMC520) += dmc520_edac.o obj-$(CONFIG_EDAC_NPCM) += npcm_edac.o obj-$(CONFIG_EDAC_ZYNQMP) += zynqmp_edac.o -obj-$(CONFIG_EDAC_PHYTIUM_PE220X) += phytium_pe220x_edac.o diff --git a/drivers/edac/phytium_pe220x_edac.c b/drivers/edac/phytium_pe220x_edac.c deleted file mode 100644 index 968b9cff18b..00000000000 --- a/drivers/edac/phytium_pe220x_edac.c +++ /dev/null @@ -1,480 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Phytium Pe220x EDAC (error detection and correction) - * - * Copyright (c) 2023-2024 Phytium Technology Co., Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "edac_module.h" - -#define EDAC_MOD_STR "phytium_edac" - -/* register offset */ -#define ERR_STATUS(n) (0x10 + ((n)*64)) -#define ERR_CTLR(n) (0x08 + ((n)*64)) -#define ERR_MISC0(n) (0x20 + ((n)*64)) -#define ERR_INJECT 0x7C -#define ERR_DEVID 0xFC8 -#define ERR_GSR 0xE00 - -#define CTLR_ED BIT(0) -#define CTLR_UI BIT(2) -#define CTLR_CFI BIT(8) - -#define MISC0_CEC(x) ((u64)(x) << 32) - -#define ERR_STATUS_CLEAR GENMASK(31, 0) - -#define CORRECTED_ERROR 0 -#define UNCORRECTED_ERROR 1 - -#define MAX_ERR_GROUP 3 - -struct phytium_edac { - struct device *dev; - void __iomem **ras_base; - struct dentry *dfs; - struct edac_device_ctl_info *edac_dev; -}; - -struct ras_error_info { - u32 index; - u32 error_type; - const char *error_str; -}; - -/* error severity definition */ -enum { - SEV_NO = 0x0, - SEV_CORRECTED = 0x1, - SEV_RECOVERABLE = 0x2, - SEV_PANIC = 0x3, -}; - -/* soc error record */ -static const struct ras_error_info pe220x_ras_soc_error[] = { - { 0, UNCORRECTED_ERROR, "lsd_nfc_ras_error" }, - { 1, UNCORRECTED_ERROR, "lsd_lpc_ras_long_wait_to" }, - { 2, UNCORRECTED_ERROR, "lsd_lpc_ras_short_wait_to" }, - { 3, UNCORRECTED_ERROR, "lsd_lpc_ras_sync_err" }, - { 4, UNCORRECTED_ERROR, "lsd_lbc_ras_err" }, - { 5, UNCORRECTED_ERROR, "usb3_err_0" }, - { 6, UNCORRECTED_ERROR, "usb3_err_1" }, - { 7, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_nonfatal_int" }, - { 8, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_fatal_int" }, - { 9, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_trans_to_err" }, - { 10, UNCORRECTED_ERROR, "gsd_gmu_mac0_asf_protocol_err" }, - { 11, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_nonfatal_int" }, - { 12, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_fatal_int" }, - { 13, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_trans_to_err" }, - { 14, UNCORRECTED_ERROR, "gsd_gmu_mac1_asf_protocol_err" }, - { 15, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_nonfatal_int" }, - { 16, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_fatal_int" }, - { 17, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_trans_to_err" }, - { 18, UNCORRECTED_ERROR, "gsd_gmu_mac2_asf_protocol_err" }, - { 19, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_nonfatal_int" }, - { 20, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_fatal_int" }, - { 21, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_trans_to_err" }, - { 22, UNCORRECTED_ERROR, "gsd_gmu_mac3_asf_protocol_err" }, - { 23, CORRECTED_ERROR, "dmu_ras_ecc_corrected_error" }, - { 24, UNCORRECTED_ERROR, "dmu_ras_ecc_uncorrected_error" }, - { 25, UNCORRECTED_ERROR, "cci_ras_nERRIRQ" }, - { 26, UNCORRECTED_ERROR, "smmu_tcu_ras_irpt" }, - { 27, UNCORRECTED_ERROR, "smmu_tbu0_ras_irpt" }, - { 28, UNCORRECTED_ERROR, "smmu_tbu1_ras_irpt" }, - { 29, UNCORRECTED_ERROR, "smmu_tbu2_ras_irpt" }, - { 30, UNCORRECTED_ERROR, "ocm_sram_ue" }, - { 31, CORRECTED_ERROR, "ocm_sram_ce" }, - { 32, UNCORRECTED_ERROR, "int_axim_err" }, - { 33, UNCORRECTED_ERROR, "int_fatal_error" }, - { 34, UNCORRECTED_ERROR, "nEXTERRIRQ_clust0" }, - { 35, UNCORRECTED_ERROR, "nINTERRIRQ_clust0" }, - { 36, UNCORRECTED_ERROR, "nEXTERRIRQ_clust1" }, - { 37, UNCORRECTED_ERROR, "nINTERRIRQ_clust1" }, - { 38, UNCORRECTED_ERROR, "nEXTERRIRQ_clust2" }, - { 39, UNCORRECTED_ERROR, "nINTERRIRQ_clust2" }, - { 40, UNCORRECTED_ERROR, "ams_ame0_ras_err" }, - { 41, UNCORRECTED_ERROR, "ams_ame1_ras_err" }, - { 42, UNCORRECTED_ERROR, "ams_amer_ras_err" }, - { 43, UNCORRECTED_ERROR, "ras_err_ame1" }, -}; - -/* pcie controller error record */ -static const struct ras_error_info pe220x_ras_peu_psu_error[] = { - { 0, CORRECTED_ERROR, "pio_rd_addr_error" }, - { 1, UNCORRECTED_ERROR, "pio_wr_addr_error" }, - { 2, CORRECTED_ERROR, "pio_rd_timeout" }, - { 3, CORRECTED_ERROR, "pio_wr_timeout" }, - { 4, CORRECTED_ERROR, "axi_b_rsp_error" }, - { 5, CORRECTED_ERROR, "axi_r_rsp_error" }, -}; - -static const struct ras_error_info pe220x_ras_peu_error[] = { - { 0, CORRECTED_ERROR, "pio_rd_addr_error" }, - { 1, UNCORRECTED_ERROR, "pio_wr_addr_error" }, - { 2, CORRECTED_ERROR, "pio_rd_timeout" }, - { 3, CORRECTED_ERROR, "pio_wr_timeout" }, - { 4, CORRECTED_ERROR, "axi_b_rsp_error" }, - { 5, CORRECTED_ERROR, "axi_r_rsp_error" }, -}; - -static const struct ras_error_info *pe220x_ras_error[] = { - pe220x_ras_soc_error, pe220x_ras_peu_psu_error, pe220x_ras_peu_error -}; - -static inline unsigned int get_error_num(const struct phytium_edac *edac, - int err_group) -{ - unsigned int error_num = 0; - - error_num = readl(edac->ras_base[err_group] + ERR_DEVID); - - return error_num; -} - -static inline void phytium_ras_setup(const struct phytium_edac *edac) -{ - u64 val = 0; - unsigned int i = 0; - /* - * enable error report and generate interrupt for corrected error event - * first error record owned by node present the node configuration - */ - for (i = 0; i < MAX_ERR_GROUP; i++) { - val = readq(edac->ras_base[i] + ERR_CTLR(0)); - val |= CTLR_ED | CTLR_UI | CTLR_CFI; - writeq(val, edac->ras_base[i] + ERR_CTLR(0)); - } -} - -static ssize_t phytium_edac_inject_ctrl_write(struct file *filp, - const char __user *buf, - size_t size, loff_t *ppos) -{ - int ret = 0; - int res = 0; - unsigned int error_group = 0; - unsigned int error_id = 0; - unsigned int error_num = 0; - struct phytium_edac *edac = filp->private_data; - char str[255]; - char *p_str = str; - char *tmp = NULL; - - if (size > 255) { - ret = -EFAULT; - goto out; - } - - if (copy_from_user(str, buf, size)) { - ret = -EFAULT; - goto out; - } else { - *ppos += size; - ret = size; - } - str[size] = '\0'; - - tmp = strsep(&p_str, ","); - if (!tmp) - goto out; - - res = kstrtouint(tmp, 0, &error_group); - if (res || error_group >= MAX_ERR_GROUP) { - dev_err(edac->dev, "invalid error group parameters"); - goto out; - } - - res = kstrtouint(p_str, 0, &error_id); - if (res) { - dev_err(edac->dev, "invalid error id parameters"); - goto out; - } - - error_num = get_error_num(edac, error_group); - if (error_id >= error_num) { - dev_err(edac->dev, "invalid ras error id.\n"); - goto out; - } - - dev_dbg(edac->dev, "inject group%d, error_id: %d\n", error_group, - error_id); - - if (pe220x_ras_error[error_group][error_id].error_type == - CORRECTED_ERROR) { - writeq(MISC0_CEC(0xFF), - edac->ras_base[error_group] + ERR_MISC0(error_id)); - } - - writel(error_id, edac->ras_base[error_group] + ERR_INJECT); - -out: - return ret; -} - -static const struct file_operations phytium_edac_debug_inject_fops[] = { - { - .open = simple_open, - .write = phytium_edac_inject_ctrl_write, - .llseek = generic_file_llseek, - }, - {} -}; - -static void phytium_edac_create_debugfs_nodes(struct phytium_edac *edac) -{ - if (!IS_ENABLED(CONFIG_EDAC_DEBUG) || !edac->dfs) { - dev_info(edac->dev, "edac debug is disable"); - return; - } - - edac_debugfs_create_file("error_inject_ctrl", 0x0200, edac->dfs, edac, - &phytium_edac_debug_inject_fops[0]); -} - -static int phytium_edac_device_add(struct phytium_edac *edac) -{ - struct edac_device_ctl_info *edac_dev; - int res = 0; - - edac_dev = edac_device_alloc_ctl_info( - sizeof(struct edac_device_ctl_info), "ras", 1, "soc", 1, 0, - NULL, 0, edac_device_alloc_index()); - if (!edac_dev) - res = -ENOMEM; - - edac_dev->dev = edac->dev; - edac_dev->mod_name = EDAC_MOD_STR; - edac_dev->ctl_name = "phytium ras"; - edac_dev->dev_name = "soc"; - - phytium_edac_create_debugfs_nodes(edac); - - res = edac_device_add_device(edac_dev); - if (res > 0) { - dev_err(edac->dev, "edac_device_add_device failed\n"); - goto err_free; - } - - edac->edac_dev = edac_dev; - dev_info(edac->dev, "phytium edac device registered\n"); - return 0; - -err_free: - edac_device_free_ctl_info(edac_dev); - return res; -} - -static int phytium_edac_device_remove(struct phytium_edac *edac) -{ - struct edac_device_ctl_info *edac_dev = edac->edac_dev; - - debugfs_remove_recursive(edac->dfs); - edac_device_del_device(edac_dev->dev); - edac_device_free_ctl_info(edac_dev); - return 0; -} - -static int get_error_id(struct phytium_edac *edac, int *error_id, - int *error_group) -{ - unsigned int error_num = 0; - u64 error_bit = 0; - int ret = 0; - int i = 0; - int err_id = 0; - - /* Iterate over the ras node to check error status */ - for (i = 0; i < MAX_ERR_GROUP; i++) { - error_num = get_error_num(edac, i); - error_bit = readq(edac->ras_base[i] + ERR_GSR); - for (err_id = 0; err_id < error_num; err_id++) { - if (!(error_bit & BIT(err_id))) - continue; - else - break; - } - if (err_id < error_num) { - *error_id = err_id; - *error_group = i; - break; - } - } - - if (i >= MAX_ERR_GROUP) { - ret = -1; - dev_warn(edac->dev, "no error detect.\n"); - } - - return ret; -} - -static void phytium_edac_error_report(struct phytium_edac *edac, - const int error_id, const int error_group) -{ - const struct ras_error_info *err_info = pe220x_ras_error[error_group]; - - if (err_info[error_id].error_type == UNCORRECTED_ERROR) { - edac_printk(KERN_CRIT, EDAC_MOD_STR, "uncorrected error: %s\n", - err_info[error_id].error_str); - edac_device_handle_ue(edac->edac_dev, 0, 0, - err_info[error_id].error_str); - /* Report the error via the trace interface */ - if (IS_ENABLED(CONFIG_RAS)) - trace_non_standard_event( (guid_t *)&NULL_UUID_LE, - (guid_t *)&NULL_UUID_LE, EDAC_MOD_STR, - SEV_RECOVERABLE, err_info[error_id].error_str, - strlen(err_info[error_id].error_str)); - } else { - edac_printk(KERN_CRIT, EDAC_MOD_STR, "corrected error: %s\n", - err_info[error_id].error_str); - edac_device_handle_ce(edac->edac_dev, 0, 0, - err_info[error_id].error_str); - if (IS_ENABLED(CONFIG_RAS)) - trace_non_standard_event( (guid_t *)&NULL_UUID_LE, - (guid_t *)&NULL_UUID_LE, EDAC_MOD_STR, - SEV_CORRECTED, err_info[error_id].error_str, - strlen(err_info[error_id].error_str)); - } -} - -/* - * clear error status and set correct error counter to 0xFE for trigger - * interrupt when next correct error event - */ -static void phytium_edac_clear_error_status(struct phytium_edac *edac, - const int error_id, - const int error_group) -{ - writeq(MISC0_CEC(0XFE), - edac->ras_base[error_group] + ERR_MISC0(error_id)); - writeq(GENMASK(31, 0), - edac->ras_base[error_group] + ERR_STATUS(error_id)); -} - -static irqreturn_t phytium_edac_isr(int irq, void *dev_id) -{ - struct phytium_edac *edac = dev_id; - int ret = 0; - int error_group; - int error_id; - - ret = get_error_id(edac, &error_id, &error_group); - if (ret < 0) - goto out; - - phytium_edac_error_report(edac, error_id, error_group); - phytium_edac_clear_error_status(edac, error_id, error_group); - -out: - return IRQ_HANDLED; -} - -static int phytium_edac_probe(struct platform_device *pdev) -{ - struct phytium_edac *edac; - struct resource *res; - int ret = 0; - int irq_cnt = 0; - int irq = 0; - int i = 0; - - edac = devm_kzalloc(&pdev->dev, sizeof(*edac), GFP_KERNEL); - if (!edac) { - ret = -ENOMEM; - goto out; - } - - edac->dev = &pdev->dev; - platform_set_drvdata(pdev, edac); - - edac->ras_base = devm_kcalloc(&pdev->dev, 3, sizeof(*edac->ras_base), - GFP_KERNEL); - if (!edac->ras_base) { - return -ENOMEM; - goto out; - } - - for (i = 0; i < MAX_ERR_GROUP; i++) { - res = platform_get_resource(pdev, IORESOURCE_MEM, i); - edac->ras_base[i] = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(edac->ras_base[i])) { - dev_err(&pdev->dev, "no resource address\n"); - ret = PTR_ERR(edac->ras_base[i]); - goto out; - } - } - - edac->dfs = edac_debugfs_create_dir(EDAC_MOD_STR); - - ret = phytium_edac_device_add(edac); - if (ret) { - dev_err(&pdev->dev, "can't add edac device"); - goto out; - } - - phytium_ras_setup(edac); - - irq_cnt = platform_irq_count(pdev); - if (irq_cnt < 0) { - dev_err(&pdev->dev, "no irq resource\n"); - ret = -EINVAL; - goto out; - } - - for (i = 0; i < irq_cnt; i++) { - irq = platform_get_irq(pdev, i); - if (irq < 0) { - dev_err(&pdev->dev, "invalid irq resource\n"); - ret = -EINVAL; - goto out; - } - ret = devm_request_irq(&pdev->dev, irq, phytium_edac_isr, - IRQF_SHARED, EDAC_MOD_STR, edac); - if (ret) { - dev_err(&pdev->dev, "could not request irq %d\n", irq); - goto out; - } - } - -out: - return ret; -} - -static int phytium_edac_remove(struct platform_device *pdev) -{ - struct phytium_edac *edac = dev_get_drvdata(&pdev->dev); - - phytium_edac_device_remove(edac); - - return 0; -} - -static const struct of_device_id phytium_edac_of_match[] = { - { .compatible = "phytium,pe220x-edac" }, - {}, -}; -MODULE_DEVICE_TABLE(of, phytium_edac_of_match); - -static struct platform_driver phytium_edac_driver = { - .probe = phytium_edac_probe, - .remove = phytium_edac_remove, - .driver = { - .name = "phytiumi-pe220x-edac", - .of_match_table = phytium_edac_of_match, - }, -}; - -module_platform_driver(phytium_edac_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Huang Jie "); -- Gitee From 8ff84df99873978bde4541a91c015b6da63c9705 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Wed, 26 Apr 2023 15:00:09 +0800 Subject: [PATCH 42/71] net: macb: fix rx error when set mtu 128 Before this patch, when set mtu 128 will have rx error, because rx buffer size is related with mtu and will small than standard frame. Most ethernet driver will set rx buffer size at least the size of standard frame to avoid this case happen. Signed-off-by: liutianyu1250 --- drivers/net/ethernet/cadence/macb_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index a836921fb0b..f66fd22aa1d 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -3344,7 +3344,10 @@ static void macb_set_rx_mode(struct net_device *dev) static int macb_open(struct net_device *dev) { - size_t bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN; + /* adjust bufsz to be at least the size of a standard frame, + * to fix rx error when set small size mtu. + */ + size_t bufsz = (dev->mtu < ETH_DATA_LEN ? ETH_DATA_LEN : dev->mtu) + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN; struct macb *bp = netdev_priv(dev); struct macb_queue *queue; unsigned int q; -- Gitee From 068ddff027da0426f2f98c879818939ad661ac9f Mon Sep 17 00:00:00 2001 From: shiguangyuan Date: Thu, 8 Dec 2022 08:54:51 +0800 Subject: [PATCH 43/71] drivers: net/ethernet/cadence: expand jumbo_ max_ Len to 16360 to support jumbo frames Signed-off-by: shiguangyuan Signed-off-by: liutianyu1250 --- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index f66fd22aa1d..fd4256912b5 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -5428,7 +5428,7 @@ static const struct macb_config phytium_gem1p0_config = { .dma_burst_length = 16, .clk_init = phytium_clk_init, .init = macb_init, - .jumbo_max_len = 10240, + .jumbo_max_len = 16360, .sel_clk_hw = phytium_gem1p0_sel_clk, .usrio = &macb_default_usrio, }; -- Gitee From d7103f48d741cf6864f70107b3bd92ff11d1d2e6 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Mon, 15 Apr 2024 17:06:42 +0800 Subject: [PATCH 44/71] net: macb: phytium: add new macb_config temporaily For some reasons, add new macb_config support. It will be removed in the future. Signed-off-by: liutianyu1250 --- drivers/net/ethernet/cadence/macb.h | 4 ++ drivers/net/ethernet/cadence/macb_main.c | 52 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 3a5441dcc73..bff334e15c9 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -186,6 +186,7 @@ #define GEM_DCFG12 0x02AC /* Design Config 12 */ #define GEM_USX_CONTROL 0x0A80 /* High speed PCS control register */ #define GEM_USX_STATUS 0x0A88 /* High speed PCS status register */ +#define GEM_TAIL_ENABLE 0x0E7C /* Phytium: Enable tail */ #define GEM_TXBDCTRL 0x04cc /* TX Buffer Descriptor control register */ #define GEM_RXBDCTRL 0x04d0 /* RX Buffer Descriptor control register */ @@ -220,6 +221,7 @@ #define GEM_IER(hw_q) (0x0600 + ((hw_q) << 2)) #define GEM_IDR(hw_q) (0x0620 + ((hw_q) << 2)) #define GEM_IMR(hw_q) (0x0640 + ((hw_q) << 2)) +#define GEM_TAIL(hw_q) (0x0e80 + ((hw_q) << 2)) /* Phytium: tail register */ #define GEM_SRC_SEL_LN 0x1C04 #define GEM_DIV_SEL0_LN 0x1C08 @@ -770,6 +772,7 @@ #define MACB_CAPS_MIIONRGMII 0x00000200 #define MACB_CAPS_NEED_TSUCLK 0x00000400 #define MACB_CAPS_SEL_CLK 0x00000800 +#define MACB_CAPS_TAILPTR 0x00001000 /* Phytium: tail register */ #define MACB_CAPS_PCS 0x01000000 #define MACB_CAPS_HIGH_SPEED 0x02000000 #define MACB_CAPS_CLK_HW_CHG 0x04000000 @@ -1260,6 +1263,7 @@ struct macb_queue { unsigned int RBQS; unsigned int RBQP; unsigned int RBQPH; + unsigned int TAILADDR; /* Lock to protect tx_head and tx_tail */ spinlock_t tx_ptr_lock; diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index fd4256912b5..383a692fe38 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -923,6 +923,29 @@ static void phytium_gem2p0_sel_clk(struct macb *bp, int speed) gem_readl(bp, HS_MAC_CONFIG))); } +static void phytium_gmac_sel_clk(struct macb *bp, int spd) +{ + int speed = 0; + + if (bp->phy_interface == PHY_INTERFACE_MODE_USXGMII || + bp->phy_interface == PHY_INTERFACE_MODE_10GBASER) { + speed = HS_SPEED_10000M; + } else if (bp->phy_interface == PHY_INTERFACE_MODE_5GBASER) { + speed = HS_SPEED_5000M; + } else if (bp->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { + speed = HS_SPEED_2500M; + } else if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { + if (spd == SPEED_1000) { + speed = HS_SPEED_1000M; + } else if (spd == SPEED_100 || spd == SPEED_10) { + speed = HS_SPEED_100M; + } + } + + gem_writel(bp, HS_MAC_CONFIG, GEM_BFINS(HS_MAC_SPEED, speed, + gem_readl(bp, HS_MAC_CONFIG))); +} + static void macb_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, @@ -2661,6 +2684,9 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev) wmb(); skb_tx_timestamp(skb); + if (bp->caps & MACB_CAPS_TAILPTR) + queue_writel(queue, TAILADDR, BIT(31) | macb_tx_ring_wrap(bp, queue->tx_head)); + spin_lock_irq(&bp->lock); macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); spin_unlock_irq(&bp->lock); @@ -2950,6 +2976,9 @@ static void gem_init_rings(struct macb *bp) queue->tx_head = 0; queue->tx_tail = 0; + if (bp->caps & MACB_CAPS_TAILPTR) + queue_writel(queue, TAILADDR, BIT(31) | queue->tx_head); + for (i = 0; i < bp->rx_ring_size; i++) { desc = macb_rx_desc(queue, i); desc->ctrl = 0; @@ -3220,6 +3249,9 @@ static void macb_init_hw(struct macb *bp) bp->duplex = DUPLEX_HALF; } + if (bp->caps & MACB_CAPS_TAILPTR) + gem_writel(bp, TAIL_ENABLE, 0x80000001); + macb_configure_dma(bp); } @@ -4619,6 +4651,9 @@ static int macb_init(struct platform_device *pdev) #endif } + if (bp->caps & MACB_CAPS_TAILPTR) + queue->TAILADDR = GEM_TAIL(hw_q); + /* get irq: here we use the linux queue index, not the hardware * queue index. the queue irq definitions in the device tree * must remove the optional gaps that could exist in the @@ -5447,6 +5482,21 @@ static const struct macb_config phytium_gem2p0_config = { .usrio = &macb_default_usrio, }; +static const struct macb_config phytium_gmac_config = { + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | + MACB_CAPS_JUMBO | + MACB_CAPS_GEM_HAS_PTP | + MACB_CAPS_BD_RD_PREFETCH | + MACB_CAPS_SEL_CLK | + MACB_CAPS_TAILPTR, + .dma_burst_length = 16, + .clk_init = phytium_clk_init, + .init = macb_init, + .jumbo_max_len = 10240, + .sel_clk_hw = phytium_gmac_sel_clk, + .usrio = &macb_default_usrio, +}; + static const struct of_device_id macb_dt_ids[] = { { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, { .compatible = "cdns,macb" }, @@ -5472,6 +5522,7 @@ static const struct of_device_id macb_dt_ids[] = { { .compatible = "xlnx,versal-gem", .data = &versal_config}, { .compatible = "cdns,phytium-gem-1.0", .data = &phytium_gem1p0_config }, { .compatible = "cdns,phytium-gem-2.0", .data = &phytium_gem2p0_config }, + { .compatible = "phytium,gmac-1.0", .data = &phytium_gmac_config }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, macb_dt_ids); @@ -5480,6 +5531,7 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids); #ifdef CONFIG_ACPI static const struct acpi_device_id macb_acpi_ids[] = { { .id = "PHYT0036", .driver_data = (kernel_ulong_t)&phytium_gem1p0_config }, + { .id = "PHYT0046", .driver_data = (kernel_ulong_t)&phytium_gmac_config }, { } }; -- Gitee From 6e37785b27bb8db04bd2fd802eeff10407948872 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Tue, 16 Apr 2024 09:27:01 +0800 Subject: [PATCH 45/71] net: macb: phytium: fix macb_open with fixed-link failed When use fixed-link phylink, try to connect phy will be cut, ... ------------[ cut here ]------------ WARNING: CPU: 4 PID: 275 at drivers/net/phy/phylink.c:1855 phylink_connect_phy+0xa8/0xf0 ... add check phylink_expects_phy(), if not, don't connect phy. Signed-off-by: liutianyu1250 --- drivers/net/ethernet/cadence/macb_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 383a692fe38..47cd9c2c81d 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1086,7 +1086,7 @@ static int macb_phylink_connect(struct macb *bp) struct device_node *dn = bp->pdev->dev.of_node; struct net_device *dev = bp->dev; struct phy_device *phydev; - int ret; + int ret = 0; if (dn) ret = phylink_of_phy_connect(bp->phylink, dn, 0); @@ -1099,7 +1099,8 @@ static int macb_phylink_connect(struct macb *bp) } /* attach the mac to the phy */ - ret = phylink_connect_phy(bp->phylink, phydev); + if (phylink_expects_phy(bp->phylink)) + ret = phylink_connect_phy(bp->phylink, phydev); } if (ret) { -- Gitee From 2ab550130b90665434fd80782a8a865613994748 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Sat, 11 May 2024 15:00:50 +0800 Subject: [PATCH 46/71] net: macb: phytium: add old of-compatible support If only update kernel, without dtb, macb will be not probe because compatible name changed, any way add old name here. Signed-off-by: liutianyu1250 --- drivers/net/ethernet/cadence/macb_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 47cd9c2c81d..764505c9afb 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -5521,6 +5521,7 @@ static const struct of_device_id macb_dt_ids[] = { { .compatible = "xlnx,zynqmp-gem", .data = &zynqmp_config}, { .compatible = "xlnx,zynq-gem", .data = &zynq_config }, { .compatible = "xlnx,versal-gem", .data = &versal_config}, + { .compatible = "cdns,phytium-gem", .data = &phytium_gem1p0_config }, /* old version */ { .compatible = "cdns,phytium-gem-1.0", .data = &phytium_gem1p0_config }, { .compatible = "cdns,phytium-gem-2.0", .data = &phytium_gem2p0_config }, { .compatible = "phytium,gmac-1.0", .data = &phytium_gmac_config }, -- Gitee From cd33538cc0edec6a20a5f91e596fc5201c807621 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Tue, 14 May 2024 11:38:49 +0800 Subject: [PATCH 47/71] drm/phytium: Modify PHYTIUM_DP_INTERRUPT_MASK bit value v2 Change HPD_OTHER_MASK from 0x5c to 0x7c. Signed-off-by: liutianyu1250 --- drivers/gpu/drm/phytium/phytium_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/phytium/phytium_reg.h b/drivers/gpu/drm/phytium/phytium_reg.h index 20428a89b79..f5d4a6945c3 100644 --- a/drivers/gpu/drm/phytium/phytium_reg.h +++ b/drivers/gpu/drm/phytium/phytium_reg.h @@ -268,7 +268,7 @@ #define PHYTIUM_DP_INTERRUPT_MASK 0x0144 #define HPD_IRQ_MASK (1<<1) #define HPD_EVENT_MASK (1<<0) - #define HPD_OTHER_MASK 0x5c + #define HPD_OTHER_MASK 0x7c #define PHYTIUM_DP_AUX_REPLY_DATA_COUNT 0x0148 #define PHYTIUM_DP_AUX_STATUS 0x014C #define REPLY_RECEIVED 0x1 -- Gitee From 66554ad524bbb0e1b0c8c3517387e83e56163e27 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Wed, 15 May 2024 16:06:30 +0800 Subject: [PATCH 48/71] arm64: dts: add optee node in pe220x Signed-off-by: liutianyu1250 --- arch/arm64/boot/dts/phytium/pe220x.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/phytium/pe220x.dtsi b/arch/arm64/boot/dts/phytium/pe220x.dtsi index 5bc57fa6dc1..ffa40415255 100644 --- a/arch/arm64/boot/dts/phytium/pe220x.dtsi +++ b/arch/arm64/boot/dts/phytium/pe220x.dtsi @@ -49,6 +49,10 @@ scmi_sensors0: protocol@15 { #thermal-sensor-cells = <1>; }; }; + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; }; thermal_zones: thermal-zones { -- Gitee From 2c8967a298869b590e118c9bc2f7a5fdd2a71338 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Wed, 15 May 2024 16:06:55 +0800 Subject: [PATCH 49/71] arm64: configs: add phytium_optee.config Signed-off-by: liutianyu1250 --- arch/arm64/configs/phytium_optee.config | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 arch/arm64/configs/phytium_optee.config diff --git a/arch/arm64/configs/phytium_optee.config b/arch/arm64/configs/phytium_optee.config new file mode 100644 index 00000000000..07554cf843d --- /dev/null +++ b/arch/arm64/configs/phytium_optee.config @@ -0,0 +1,2 @@ +CONFIG_TEE=y +CONFIG_OPTEE=y -- Gitee From fe6a247e0678f54f1fb3cfa6ad209e61e25795f1 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 16 May 2024 10:24:08 +0800 Subject: [PATCH 50/71] sound: phytium: correct i2c acpi id name Signed-off-by: liutianyu1250 --- sound/soc/phytium/phytium_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/phytium/phytium_i2s.c b/sound/soc/phytium/phytium_i2s.c index 0ac36260ce6..9119cdae1c2 100644 --- a/sound/soc/phytium/phytium_i2s.c +++ b/sound/soc/phytium/phytium_i2s.c @@ -1411,7 +1411,7 @@ static const struct acpi_device_id phytium_i2s_acpi_match[] = { { "PHYT0016", 0 }, { } }; -MODULE_DEVICE_TABLE(acpi, phytium_i2s_acpi_ids); +MODULE_DEVICE_TABLE(acpi, phytium_i2s_acpi_match); #else #define phytium_i2s_acpi_match NULL #endif -- Gitee From 6e9b12356c04d0606966ce1993072c4d553c5bca Mon Sep 17 00:00:00 2001 From: zuoqian Date: Tue, 14 May 2024 16:28:59 +0800 Subject: [PATCH 51/71] i2c: pcie: phytium: add a module parameter to enable msi Signed-off-by: zuoqian --- drivers/i2c/busses/i2c-phytium-pci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/i2c/busses/i2c-phytium-pci.c b/drivers/i2c/busses/i2c-phytium-pci.c index 0818b9db103..c63abddd09b 100644 --- a/drivers/i2c/busses/i2c-phytium-pci.c +++ b/drivers/i2c/busses/i2c-phytium-pci.c @@ -29,6 +29,10 @@ #define DRV_NAME "i2c-phytium-pci" +int i2c_msi_enable; +module_param(i2c_msi_enable, int, 0644); +MODULE_PARM_DESC(i2c_msi_enable, "Enable I2C msi interrupt (0-disabled; 1-enabled; default-0)"); + enum phytium_pci_ctl_id_t { octopus_i2c, }; @@ -162,6 +166,16 @@ static int i2c_phytium_pci_probe(struct pci_dev *pdev, goto out; } + if (i2c_msi_enable) { + pci_set_master(pdev); + + ret = pci_enable_msi(pdev); + if (ret) { + dev_dbg(&pdev->dev, "Error enabling MSI. ret = %d\n", ret); + goto out; + } + } + dev->controller = controller; dev->get_clk_rate_khz = i2c_phytium_get_clk_rate_khz; dev->base = pcim_iomap_table(pdev)[0]; -- Gitee From adf605e6f5360a9e7fa43839f4df1346ef8997a1 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Wed, 17 Apr 2024 10:50:32 +0800 Subject: [PATCH 52/71] sound: pmdk_dp: fix DAPM unknown pin error log at boot there is no HDMI/DP dapm widget in PDMKI2S sound card, is unnecessary to associate DAPM pins widget with jack Signed-off-by: Huangjie --- sound/soc/phytium/pmdk_dp.c | 40 +++++++------------------------------ 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/sound/soc/phytium/pmdk_dp.c b/sound/soc/phytium/pmdk_dp.c index aedbf2696e3..85ff8e5667a 100644 --- a/sound/soc/phytium/pmdk_dp.c +++ b/sound/soc/phytium/pmdk_dp.c @@ -31,27 +31,6 @@ static const struct snd_soc_dapm_route pmdk_dp_audio_map[] = { {"DP", NULL, "TX"}, }; -static struct snd_soc_jack_pin dp0_pins[] = { - { - .pin = "HDMI/DP,pcm=0", - .mask = SND_JACK_LINEOUT, - }, -}; - -static struct snd_soc_jack_pin dp1_pins[] = { - { - .pin = "HDMI/DP,pcm=1", - .mask = SND_JACK_LINEOUT, - }, -}; - -static struct snd_soc_jack_pin dp2_pins[] = { - { - .pin = "HDMI/DP,pcm=2", - .mask = SND_JACK_LINEOUT, - }, -}; - #define SMDK_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ SND_SOC_DAIFMT_CBS_CFS) @@ -62,10 +41,8 @@ static int pmdk_dp0_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; int ret; - ret = snd_soc_card_jack_new_pins(card, "HDMI/DP,pcm=0", - SND_JACK_LINEOUT, - &priv->jack0, dp0_pins, - ARRAY_SIZE(dp0_pins)); + ret = snd_soc_card_jack_new(card, "HDMI/DP,pcm=0", SND_JACK_LINEOUT, + &priv->jack0); if (ret) { dev_err(card->dev, "Jack creation failed %d\n", ret); @@ -83,10 +60,8 @@ static int pmdk_dp1_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; int ret; - ret = snd_soc_card_jack_new_pins(card, "HDMI/DP,pcm=1", - SND_JACK_LINEOUT, - &priv->jack1, dp1_pins, - ARRAY_SIZE(dp1_pins)); + ret = snd_soc_card_jack_new(card, "HDMI/DP,pcm=1", SND_JACK_LINEOUT, + &priv->jack1); if (ret) { dev_err(card->dev, "Jack creation failed %d\n", ret); @@ -103,10 +78,9 @@ static int pmdk_dp2_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; int ret; - ret = snd_soc_card_jack_new_pins(card, "HDMI/DP,pcm=2", - SND_JACK_LINEOUT, - &priv->jack2, dp2_pins, - ARRAY_SIZE(dp2_pins)); + ret = snd_soc_card_jack_new(card, "HDMI/DP,pcm=2", SND_JACK_LINEOUT, + &priv->jack2); + if (ret) { dev_err(card->dev, "Jack creation failed %d\n", ret); return ret; -- Gitee From cf43805f95c45701f965a02d08e6f658ba03c4e2 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Mon, 22 Apr 2024 14:34:41 +0800 Subject: [PATCH 53/71] drivers: mmc: start timeout timer before send request previously, we send request first then start timer, sometimes caused mmc interrupt triggered before mod_timer and print "request timeout" log Signed-off-by: Huangjie --- drivers/mmc/host/phytium-mci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/phytium-mci.c b/drivers/mmc/host/phytium-mci.c index b5e4ee3e9d7..b067f8b4dd9 100644 --- a/drivers/mmc/host/phytium-mci.c +++ b/drivers/mmc/host/phytium-mci.c @@ -680,6 +680,8 @@ phytium_mci_start_data(struct phytium_mci_host *host, struct mmc_request *mrq, phytium_mci_data_sg_write_2_fifo(host, data); spin_lock_irqsave(&host->lock, flags); + mod_timer(&host->timeout_timer, + jiffies + msecs_to_jiffies(MMC_REQ_TIMEOUT_MS)); sdr_set_bits(host->base + MCI_INT_MASK, cmd_ints_mask | data_ints_mask); if (host->is_use_dma && host->adtc_type == BLOCK_RW_ADTC) { sdr_set_bits(host->base + MCI_DMAC_INT_ENA, dmac_ints_mask); @@ -695,9 +697,6 @@ phytium_mci_start_data(struct phytium_mci_host *host, struct mmc_request *mrq, wmb(); /* drain writebuffer */ writel(rawcmd, host->base + MCI_CMD); spin_unlock_irqrestore(&host->lock, flags); - - mod_timer(&host->timeout_timer, - jiffies + msecs_to_jiffies(MMC_REQ_TIMEOUT_MS)); } static void phytium_mci_track_cmd_data(struct phytium_mci_host *host, @@ -804,13 +803,12 @@ static void phytium_mci_start_command(struct phytium_mci_host *host, } spin_lock_irqsave(&host->lock, flags); + mod_timer(&host->timeout_timer, + jiffies + msecs_to_jiffies(MMC_REQ_TIMEOUT_MS)); sdr_set_bits(host->base + MCI_INT_MASK, cmd_ints_mask); writel(cmd->arg, host->base + MCI_CMDARG); writel(rawcmd, host->base + MCI_CMD); spin_unlock_irqrestore(&host->lock, flags); - - mod_timer(&host->timeout_timer, - jiffies + msecs_to_jiffies(MMC_REQ_TIMEOUT_MS)); } static void -- Gitee From 9159ce273c6e127aa3c41ac471af3121a360ab1a Mon Sep 17 00:00:00 2001 From: Huangjie Date: Thu, 23 May 2024 14:33:04 +0800 Subject: [PATCH 54/71] driver: arm_scmi: fix scmi transfer timeout in preemption kernel 1. poll transfer status after reach timeout, scmi transfer timeout maybe caused by preempt during polling stage 2. add lock for scmi transfer, not set the scmi transfer into waiting response stage too early Signed-off-by: Huangjie --- drivers/firmware/arm_scmi/driver.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 87383c05424..6a16007c60b 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -51,6 +51,8 @@ static DEFINE_SPINLOCK(protocol_lock); static LIST_HEAD(scmi_list); /* Protection for the entire list */ static DEFINE_MUTEX(scmi_list_mutex); +/* Protection for scmi xfer, prevent transmission timeout */ +static DEFINE_MUTEX(scmi_xfer_mutex); /* Track the unique id for the transfers for debug & profiling purpose */ static atomic_t transfer_last_id; @@ -1030,6 +1032,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, struct scmi_xfer *xfer, unsigned int timeout_ms) { int ret = 0; + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); if (xfer->hdr.poll_completion) { /* @@ -1045,7 +1048,10 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop)); - if (ktime_after(ktime_get(), stop)) { + + /* Poll again, timeout maybe caused by preempted */ + if (ktime_after(ktime_get(), stop) && + !info->desc->ops->poll_done(cinfo, xfer)) { dev_err(dev, "timed out in resp(caller: %pS) - polling\n", (void *)_RET_IP_); @@ -1211,8 +1217,11 @@ static int do_xfer(const struct scmi_protocol_handle *ph, */ smp_mb(); + /* lock scmi xfer, too many scmi xfers may cause timeout */ + mutex_lock(&scmi_xfer_mutex); ret = info->desc->ops->send_message(cinfo, xfer); if (ret < 0) { + mutex_unlock(&scmi_xfer_mutex); dev_dbg(dev, "Failed to send message %d\n", ret); return ret; } @@ -1228,6 +1237,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph, if (info->desc->ops->mark_txdone) info->desc->ops->mark_txdone(cinfo, ret, xfer); + mutex_unlock(&scmi_xfer_mutex); + trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id, xfer->hdr.protocol_id, xfer->hdr.seq, ret); -- Gitee From 05bbfc6d6f2c351d0b27f73a0fe6eb6094aadcc0 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Mon, 13 Feb 2023 17:48:40 +0800 Subject: [PATCH 55/71] drivers: mmc: fix some sd card init fail Sometimes host get ACMD41 cmd done irq but the respose index still the APP_CMD(CMD55), so polling the mci status entill the respose index change. Signed-off-by: liutianyu1250 --- drivers/mmc/host/phytium-mci.c | 15 +++++++++++++++ drivers/mmc/host/phytium-mci.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/mmc/host/phytium-mci.c b/drivers/mmc/host/phytium-mci.c index b067f8b4dd9..4a938fea360 100644 --- a/drivers/mmc/host/phytium-mci.c +++ b/drivers/mmc/host/phytium-mci.c @@ -756,6 +756,21 @@ static bool phytium_mci_cmd_done(struct phytium_mci_host *host, int events, rsp[1] = readl(host->base + MCI_RESP2); rsp[0] = readl(host->base + MCI_RESP3); } else { + /* + * Sometimes get ACMD41 cmd done irq but the respose index still the APP_CMD, + * so polling the mci status entill the respose index change. + */ + if (cmd->opcode == SD_APP_OP_COND) { + int polling_cnt = 20; + while (MMC_APP_CMD == MCI_STATUS_RESPOSE_INDEX(readl(host->base + MCI_STATUS))) { + udelay(100); + polling_cnt --; + if (polling_cnt == 0) { + dev_info(host->dev, "hw respose index not equal cmd opcode, respose value may error\n"); + break; + } + } + } rsp[0] = readl(host->base + MCI_RESP0); } diff --git a/drivers/mmc/host/phytium-mci.h b/drivers/mmc/host/phytium-mci.h index fbe30a2df92..90f51b9ee13 100644 --- a/drivers/mmc/host/phytium-mci.h +++ b/drivers/mmc/host/phytium-mci.h @@ -217,6 +217,9 @@ #define MCI_STATUS_CARD_STATUS (0x1 << 8) /* RO */ #define MCI_STATUS_CARD_BUSY (0x1 << 9) /* RO */ #define MCI_STATUS_DATA_BUSY (0x1 << 10) /* RO */ +#define MCI_STATUS_RESPOSE_INDEX_OFFSET (11) +#define MCI_STATUS_RESPOSE_INDEX_MASK (0x3f << MCI_STATUS_RESPOSE_INDEX_OFFSET) /* RO */ +#define MCI_STATUS_RESPOSE_INDEX(reg) (((reg) & MCI_STATUS_RESPOSE_INDEX_MASK) >> MCI_STATUS_RESPOSE_INDEX_OFFSET) #define MCI_STATUS_DMA_ACK (0x1 << 31) /* RO */ #define MCI_STATUS_DMA_REQ (0x1 << 32) /* RO */ -- Gitee From 1a83311c91c66dda6ceb7ea40aefefc6d91bd485 Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Fri, 3 Nov 2023 10:08:51 +0800 Subject: [PATCH 56/71] wifi: rtw88: fix RX filter in FIF_ALLMULTI flag [ Upstream commit 53ee0b3b99edc6a47096bffef15695f5a895386f ] The broadcast packets will be filtered in the FIF_ALLMULTI flag in the original code, which causes beacon packets to be filtered out and disconnection. Therefore, we fix it. Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20231103020851.102238-1-pkshih@realtek.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/mac80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index a99b53d4426..d8d68f16014 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -280,9 +280,9 @@ static void rtw_ops_configure_filter(struct ieee80211_hw *hw, if (changed_flags & FIF_ALLMULTI) { if (*new_flags & FIF_ALLMULTI) - rtwdev->hal.rcr |= BIT_AM | BIT_AB; + rtwdev->hal.rcr |= BIT_AM; else - rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); + rtwdev->hal.rcr &= ~(BIT_AM); } if (changed_flags & FIF_FCSFAIL) { if (*new_flags & FIF_FCSFAIL) -- Gitee From cd0ceff12221563c2c700b32ab97317c49e30233 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 20 Nov 2023 12:57:26 +0100 Subject: [PATCH 57/71] wifi: rtw88: sdio: Honor the host max_req_size in the RX path [ Upstream commit 00384f565a91c08c4bedae167f749b093d10e3fe ] Lukas reports skb_over_panic errors on his Banana Pi BPI-CM4 which comes with an Amlogic A311D (G12B) SoC and a RTL8822CS SDIO wifi/Bluetooth combo card. The error he observed is identical to what has been fixed in commit e967229ead0e ("wifi: rtw88: sdio: Check the HISR RX_REQUEST bit in rtw_sdio_rx_isr()") but that commit didn't fix Lukas' problem. Lukas found that disabling or limiting RX aggregation works around the problem for some time (but does not fully fix it). In the following discussion a few key topics have been discussed which have an impact on this problem: - The Amlogic A311D (G12B) SoC has a hardware bug in the SDIO controller which prevents DMA transfers. Instead all transfers need to go through the controller SRAM which limits transfers to 1536 bytes - rtw88 chips don't split incoming (RX) packets, so if a big packet is received this is forwarded to the host in it's original form - rtw88 chips can do RX aggregation, meaning more multiple incoming packets can be pulled by the host from the card with one MMC/SDIO transfer. This Depends on settings in the REG_RXDMA_AGG_PG_TH register (BIT_RXDMA_AGG_PG_TH limits the number of packets that will be aggregated, BIT_DMA_AGG_TO_V1 configures a timeout for aggregation and BIT_EN_PRE_CALC makes the chip honor the limits more effectively) Use multiple consecutive reads in rtw_sdio_read_port() and limit the number of bytes which are copied by the host from the card in one MMC/SDIO transfer. This allows receiving a buffer that's larger than the hosts max_req_size (number of bytes which can be transferred in one MMC/SDIO transfer). As a result of this the skb_over_panic error is gone as the rtw88 driver is now able to receive more than 1536 bytes from the card (either because the incoming packet is larger than that or because multiple packets have been aggregated). In case of an receive errors (-EILSEQ has been observed by Lukas) we need to drain the remaining data from the card's buffer, otherwise the card will return corrupt data for the next rtw_sdio_read_port() call. Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") Reported-by: Lukas F. Hartmann Closes: https://lore.kernel.org/linux-wireless/CAFBinCBaXtebixKbjkWKW_WXc5k=NdGNaGUjVE8NCPNxOhsb2g@mail.gmail.com/ Suggested-by: Ping-Ke Shih Signed-off-by: Martin Blumenstingl Reviewed-by: Ulf Hansson Acked-by: Ping-Ke Shih Tested-by: Lukas F. Hartmann Reported-by: Lukas F. Hartmann Signed-off-by: Martin Blumenstingl Reviewed-by: Ulf Hansson Acked-by: Ping-Ke Shih Tested-by: Lukas F. Hartmann Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20231120115726.1569323-1-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/sdio.c | 35 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index 2c1fb2dabd4..0cae5746f54 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -500,19 +500,40 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size, static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count) { struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + struct mmc_host *host = rtwsdio->sdio_func->card->host; bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); u32 rxaddr = rtwsdio->rx_addr++; - int ret; + int ret = 0, err; + size_t bytes; if (bus_claim) sdio_claim_host(rtwsdio->sdio_func); - ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, - RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count); - if (ret) - rtw_warn(rtwdev, - "Failed to read %zu byte(s) from SDIO port 0x%08x", - count, rxaddr); + while (count > 0) { + bytes = min_t(size_t, host->max_req_size, count); + + err = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, + RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), + bytes); + if (err) { + rtw_warn(rtwdev, + "Failed to read %zu byte(s) from SDIO port 0x%08x: %d", + bytes, rxaddr, err); + + /* Signal to the caller that reading did not work and + * that the data in the buffer is short/corrupted. + */ + ret = err; + + /* Don't stop here - instead drain the remaining data + * from the card's buffer, else the card will return + * corrupt data for the next rtw_sdio_read_port() call. + */ + } + + count -= bytes; + buf += bytes; + } if (bus_claim) sdio_release_host(rtwsdio->sdio_func); -- Gitee From 1240d34dcfa4702e0923becf45c886718fc64802 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 1 Mar 2024 00:32:45 +0200 Subject: [PATCH 58/71] wifi: rtw88: 8821cu: Fix firmware upload fail [ Upstream commit 41a7acb7dde8395f52a707bbba7712a898dfafb0 ] RTL8822CU, RTL8822BU, and RTL8821CU need an extra register write after reading and writing certain addresses. Without this, the firmware upload fails approximately more than 50% of the time. Tested with RTL8811CU (Tenda U9 V2.0) which is the same as RTL8821CU but without Bluetooth. Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support") Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://msgid.link/f12ed39d-28e8-4b8b-8d22-447bcf295afc@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/usb.c | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index e6ab1ac6d70..a0188511099 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -33,6 +33,36 @@ static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); } +static void rtw_usb_reg_sec(struct rtw_dev *rtwdev, u32 addr, __le32 *data) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *udev = rtwusb->udev; + bool reg_on_section = false; + u16 t_reg = 0x4e0; + u8 t_len = 1; + int status; + + /* There are three sections: + * 1. on (0x00~0xFF; 0x1000~0x10FF): this section is always powered on + * 2. off (< 0xFE00, excluding "on" section): this section could be + * powered off + * 3. local (>= 0xFE00): usb specific registers section + */ + if (addr <= 0xff || (addr >= 0x1000 && addr <= 0x10ff)) + reg_on_section = true; + + if (!reg_on_section) + return; + + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, + t_reg, 0, data, t_len, 500); + + if (status != t_len && status != -ENODEV) + rtw_err(rtwdev, "%s: reg 0x%x, usb write %u fail, status: %d\n", + __func__, t_reg, t_len, status); +} + static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len) { struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); @@ -58,6 +88,11 @@ static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len) rtw_err(rtwdev, "read register 0x%x failed with %d\n", addr, ret); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C || + rtwdev->chip->id == RTW_CHIP_TYPE_8822B || + rtwdev->chip->id == RTW_CHIP_TYPE_8821C) + rtw_usb_reg_sec(rtwdev, addr, data); + return le32_to_cpu(*data); } @@ -102,6 +137,11 @@ static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) if (ret < 0 && ret != -ENODEV && count++ < 4) rtw_err(rtwdev, "write register 0x%x failed with %d\n", addr, ret); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C || + rtwdev->chip->id == RTW_CHIP_TYPE_8822B || + rtwdev->chip->id == RTW_CHIP_TYPE_8821C) + rtw_usb_reg_sec(rtwdev, addr, data); } static void rtw_usb_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) -- Gitee From 9c3afef5abf5db772a3103ad76d390c69fadaac4 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 1 Mar 2024 00:35:09 +0200 Subject: [PATCH 59/71] wifi: rtw88: 8821c: Fix beacon loss and disconnect [ Upstream commit e1dfa21427baeb813f9a2f9ceab6b7d32c3ca425 ] Tenda U9 V2.0, which contains RTL8811CU, is practically unusable because of frequent disconnections: Feb 23 14:46:45 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-BEACON-LOSS Feb 23 14:46:46 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-DISCONNECTED bssid=90:55:de:__:__:__ reason=4 locally_generated=1 Feb 23 14:46:52 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-CONNECTED - Connection to 90:55:de:__:__:__ completed [id=0 id_str=] Feb 23 14:46:54 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-BEACON-LOSS Feb 23 14:46:55 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-DISCONNECTED bssid=90:55:de:__:__:__ reason=4 locally_generated=1 Feb 23 14:47:01 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-CONNECTED - Connection to 90:55:de:__:__:__ completed [id=0 id_str=] Feb 23 14:47:04 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-BEACON-LOSS Feb 23 14:47:05 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-DISCONNECTED bssid=90:55:de:__:__:__ reason=4 locally_generated=1 This is caused by a mistake in the chip initialisation. This version of the chip requires loading an extra AGC table right after the main one, but the extra table is being loaded at the wrong time, in rtw_chip_board_info_setup(). Move the extra AGC table loading to the right place, in rtw_phy_load_tables(). The rtw_chip_board_info_setup() can only do "software" things, and rtw_phy_load_tables() can really do IO. Fixes: 5d6651fe8583 ("rtw88: 8821c: support RFE type2 wifi NIC") Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://msgid.link/276c31d8-b9a8-4e54-a3ac-09b74657aff7@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/main.c | 2 -- drivers/net/wireless/realtek/rtw88/phy.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 4a33d2e47f3..63673005c2f 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -2027,8 +2027,6 @@ static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev) rtw_phy_setup_phy_cond(rtwdev, hal->pkg_type); rtw_phy_init_tx_power(rtwdev); - if (rfe_def->agc_btg_tbl) - rtw_load_table(rtwdev, rfe_def->agc_btg_tbl); rtw_load_table(rtwdev, rfe_def->phy_pg_tbl); rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl); rtw_phy_tx_power_by_rate_config(hal); diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index 128e75a81bf..37ef80c9091 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -1761,12 +1761,15 @@ static void rtw_load_rfk_table(struct rtw_dev *rtwdev) void rtw_phy_load_tables(struct rtw_dev *rtwdev) { + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); const struct rtw_chip_info *chip = rtwdev->chip; u8 rf_path; rtw_load_table(rtwdev, chip->mac_tbl); rtw_load_table(rtwdev, chip->bb_tbl); rtw_load_table(rtwdev, chip->agc_tbl); + if (rfe_def->agc_btg_tbl) + rtw_load_table(rtwdev, rfe_def->agc_btg_tbl); rtw_load_rfk_table(rtwdev); for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) { -- Gitee From 652747fdb128602646353c74ccc5788369f84dea Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 1 Mar 2024 00:35:58 +0200 Subject: [PATCH 60/71] wifi: rtw88: 8821c: Fix false alarm count [ Upstream commit c238adbc578eeb70cbc8fdd1bef3666b0f585b13 ] total_fa_cnt is supposed to include cck_fa_cnt and ofdm_fa_cnt, not just ofdm_fa_cnt. Fixes: 960361238b86 ("rtw88: 8821c: add false alarm statistics") Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://msgid.link/f3cb6d17-e4e4-44a7-9c9b-72aed994b5c9@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index adf224618a2..5f3a3a88c3d 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -706,9 +706,9 @@ static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) dm_info->cck_fa_cnt = cck_fa_cnt; dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; if (cck_enable) dm_info->total_fa_cnt += cck_fa_cnt; - dm_info->total_fa_cnt = ofdm_fa_cnt; crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); -- Gitee From dae9f7a0be433acea05c81dfac3f3dac7b763f05 Mon Sep 17 00:00:00 2001 From: Nick Morrow Date: Tue, 27 Feb 2024 02:34:40 +0000 Subject: [PATCH 61/71] wifi: rtw88: Add missing VID/PIDs for 8811CU and 8821CU [ Upstream commit b8a62478f3b143592d1241de1a7f5f8629ad0f49 ] Add VID/PIDs that are known to be missing for this driver. Removed /* 8811CU */ and /* 8821CU */ as they are redundant since the file is specific to those chips. Removed /* TOTOLINK A650UA v3 */ as the manufacturer. It has a REALTEK VID so it may not be specific to this adapter. Verified and tested. Cc: stable@vger.kernel.org Signed-off-by: Nick Morrow Signed-off-by: Larry Finger Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://msgid.link/4ume7mjw63u7.XlMUvUuacW2ErhOCdqlLkw2@1EHFQ.trk.elasticemail.com Signed-off-by: Sasha Levin --- .../net/wireless/realtek/rtw88/rtw8821cu.c | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cu.c b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c index 7a5cbdc31ef..e2c7d9f8768 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821cu.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c @@ -9,24 +9,36 @@ #include "usb.h" static const struct usb_device_id rtw_8821cu_id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8731, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb820, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc80c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc820, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82a, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TOTOLINK A650UA v3 */ + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* D-Link */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd811, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table); -- Gitee From 2f110b2bfc96e1edd509665a6734f5dc59664569 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 1 Mar 2024 00:34:13 +0200 Subject: [PATCH 62/71] wifi: rtw88: 8821cu: Fix connection failure commit 605d7c0b05eecb985273b1647070497142c470d3 upstream. Clear bit 8 of REG_SYS_STATUS1 after MAC power on. Without this, some RTL8821CU and RTL8811CU cannot connect to any network: Feb 19 13:33:11 ideapad2 kernel: wlp3s0f3u2: send auth to 90:55:de:__:__:__ (try 1/3) Feb 19 13:33:13 ideapad2 kernel: wlp3s0f3u2: send auth to 90:55:de:__:__:__ (try 2/3) Feb 19 13:33:14 ideapad2 kernel: wlp3s0f3u2: send auth to 90:55:de:__:__:__ (try 3/3) Feb 19 13:33:15 ideapad2 kernel: wlp3s0f3u2: authentication with 90:55:de:__:__:__ timed out The RTL8822CU and RTL8822BU out-of-tree drivers do this as well, so do it for all three types of chips. Tested with RTL8811CU (Tenda U9 V2.0). Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://msgid.link/aeeefad9-27c8-4506-a510-ef9a9a8731a4@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtw88/mac.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 298663b0358..0c1c1ff3108 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -309,6 +309,13 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); + if (pwr_on && rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { + if (chip->id == RTW_CHIP_TYPE_8822C || + chip->id == RTW_CHIP_TYPE_8822B || + chip->id == RTW_CHIP_TYPE_8821C) + rtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0)); + } + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) rtw_write32(rtwdev, REG_SDIO_HIMR, imr); -- Gitee From c16d2eaa58ff1091aa086c720fe5a838f81d1e66 Mon Sep 17 00:00:00 2001 From: Chen Zhenhua Date: Mon, 3 Jun 2024 15:09:47 +0800 Subject: [PATCH 63/71] usb: phytium: Improve the endpoint management algorithm and fix problems that some devices can cause a kernel crash. 1. When the device endpoint number is greater than 6, the endpoint management algorithm sometimes appears the endpoint management error. 2. Fix the problem that when the device uses more than 6 endpoints at the same time, the driver reports an abnormal empty pointer. Signed-off-by: zuoqian --- drivers/usb/phytium/host.c | 53 ++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/drivers/usb/phytium/host.c b/drivers/usb/phytium/host.c index 0f86dc23996..8d58eaa99dd 100644 --- a/drivers/usb/phytium/host.c +++ b/drivers/usb/phytium/host.c @@ -23,35 +23,36 @@ #define HOST_EP_NUM 16 +static void dump_ep_remap_pool(struct HOST_CTRL *priv, bool dirIn) +{ + int index, dir = 0; + + if (!dirIn) + dir = 1; + + pr_info("%s dir endpoint remap table\n", dir ? "OUT" : "IN"); + + for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) + pr_info("ep_remap_pool[%d][%d]->%d\n", dir, index, + priv->ep_remap_pool[dir][index]); +} + static int get_epnum_from_pool(struct HOST_CTRL *priv, int real_epNum, bool dirIn) { int index, dir = 0; int ret = 0; - if (!priv) + if (!priv || real_epNum == 0) return 0; if (!dirIn) dir = 1; - if (real_epNum <= MAX_INSTANCE_EP_NUM) { - if (!priv->ep_remap_pool[dir][real_epNum]) { - priv->ep_remap_pool[dir][real_epNum] = real_epNum; - ret = real_epNum; - goto out; - } - - if (priv->ep_remap_pool[dir][real_epNum] == real_epNum) { - ret = real_epNum; + for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) { + if (priv->ep_remap_pool[dir][index] == real_epNum) { + ret = index; goto out; } - } else { - for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) { - if (priv->ep_remap_pool[dir][index] == real_epNum) { - ret = index; - goto out; - } - } } for (index = 1; index <= MAX_INSTANCE_EP_NUM; index++) { @@ -62,6 +63,9 @@ static int get_epnum_from_pool(struct HOST_CTRL *priv, int real_epNum, bool dirI } } + if (index > MAX_INSTANCE_EP_NUM) + return index; + out: return ret; } @@ -71,7 +75,7 @@ static int release_epnum_from_pool(struct HOST_CTRL *priv, int real_epNum, bool int index = 0; int dir = 0; - if (!priv) + if (!priv || real_epNum == 0) return 0; if (!dirIn) @@ -150,7 +154,6 @@ static inline void disconnectHostDetect(struct HOST_CTRL *priv) if (!priv) return; - memset(priv->ep_remap_pool, 0, sizeof(priv->ep_remap_pool)); otgctrl = phytium_read8(&priv->regs->otgctrl); if ((otgctrl & OTGCTRL_ASETBHNPEN) && priv->otgState == HOST_OTG_STATE_A_SUSPEND) pr_info("Device no Response\n"); @@ -286,6 +289,8 @@ static inline void connectHostDetect(struct HOST_CTRL *priv, uint8_t otgState) if (!priv) return; + + memset(priv->ep_remap_pool, 0, sizeof(priv->ep_remap_pool)); pr_debug("otgState:0x%x pirv->otgState:0x%x\n", otgState, priv->otgState); if (priv->custom_regs) { phytium_write32(&priv->custom_regs->wakeup, 0); @@ -1310,6 +1315,11 @@ static int hc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) req->isoFramesNumber = urb->number_of_packets; req->epNum = get_epnum_from_pool(config->host_priv, usb_endpoint_num(host_ep_desc), usb_endpoint_dir_in(host_ep_desc)); + if (req->epNum > MAX_INSTANCE_EP_NUM) { + pr_err("Not enough endpoint resource for remap\n"); + dump_ep_remap_pool(priv, usb_endpoint_dir_in(host_ep_desc)); + req->epNum = MAX_INSTANCE_EP_NUM; + } if (usb_endpoint_dir_in(host_ep_desc)) { if (!usbDev->in_ep[req->epNum]) @@ -1409,6 +1419,7 @@ static void hc_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *l struct HOST_USB_DEVICE *usbDev; int ep_num; struct phytium_cusb *config; + struct HOST_CTRL *priv; config = *(struct phytium_cusb **)hcd->hcd_priv; if (!config) @@ -1417,6 +1428,8 @@ static void hc_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *l ep_num = get_epnum_from_pool(config->host_priv, usb_endpoint_num(&ld_ep->desc), usb_endpoint_dir_in(&ld_ep->desc)); + priv = config->host_priv; + usbDev = (struct HOST_USB_DEVICE *)ld_ep->hcpriv; if (!usbDev) return; @@ -1428,6 +1441,7 @@ static void hc_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *l INIT_LIST_HEAD(&usbDev->in_ep[ep_num]->reqList); kfree(usbDev->in_ep[ep_num]); usbDev->in_ep[ep_num] = NULL; + priv->ep_remap_pool[0][ep_num] = 0; } } else { if (usbDev->out_ep[ep_num]) { @@ -1435,6 +1449,7 @@ static void hc_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *l INIT_LIST_HEAD(&usbDev->out_ep[ep_num]->reqList); kfree(usbDev->out_ep[ep_num]); usbDev->out_ep[ep_num] = NULL; + priv->ep_remap_pool[1][ep_num] = 0; } } } -- Gitee From 21967afedc24215460dbe473f895234df6635910 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Tue, 4 Jun 2024 18:57:40 +0800 Subject: [PATCH 64/71] drivers: dma: add channel id in xfer logs Signed-off-by: Huangjie --- drivers/dma/phytium/phytium-ddmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dma/phytium/phytium-ddmac.c b/drivers/dma/phytium/phytium-ddmac.c index 015976378ce..5c1f8e2e81d 100644 --- a/drivers/dma/phytium/phytium-ddmac.c +++ b/drivers/dma/phytium/phytium-ddmac.c @@ -265,7 +265,7 @@ static void phytium_chan_start_xfer(struct phytium_ddma_chan *chan) chan->desc = to_ddma_desc(vdesc); chan->next_sg = 0; chan->current_sg = NULL; - dev_dbg(chan_to_dev(chan), "xfer start\n"); + dev_dbg(chan_to_dev(chan), "channel %d xfer start\n", chan->id); } if (chan->next_sg == chan->desc->num_sgs) @@ -322,7 +322,8 @@ static void phytium_chan_xfer_done(struct phytium_ddma_chan *chan) chan->busy = false; if (chan->next_sg == chan->desc->num_sgs) { - dev_dbg(chan_to_dev(chan), "xfer complete\n"); + dev_dbg(chan_to_dev(chan), + "channel %d xfer complete\n", chan->id); vchan_cookie_complete(&chan->desc->vdesc); chan->desc = NULL; chan->current_sg = NULL; -- Gitee From ca64a3f1131f5e00a97fd8d44f43084363f36c56 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Wed, 5 Jun 2024 10:57:15 +0800 Subject: [PATCH 65/71] drivers: dma: let phytium ddma driver load early Signed-off-by: Huangjie --- drivers/dma/phytium/phytium-ddmac.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/dma/phytium/phytium-ddmac.c b/drivers/dma/phytium/phytium-ddmac.c index 5c1f8e2e81d..768236d9947 100644 --- a/drivers/dma/phytium/phytium-ddmac.c +++ b/drivers/dma/phytium/phytium-ddmac.c @@ -939,7 +939,18 @@ static struct platform_driver phytium_driver = { }, }; -module_platform_driver(phytium_driver); +static __init int phytium_ddma_init(void) +{ + return platform_driver_register(&phytium_driver); +} + +static void __exit phytium_ddma_exit(void) +{ + platform_driver_unregister(&phytium_driver); +} + +subsys_initcall(phytium_ddma_init); +module_exit(phytium_ddma_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Phytium DDMA Controller platform driver"); -- Gitee From 931583d9b89681fe586e89aaf00504033a3cebcd Mon Sep 17 00:00:00 2001 From: Huangjie Date: Wed, 5 Jun 2024 10:58:41 +0800 Subject: [PATCH 66/71] drivers: dma: make PHYTIUM_DDMA bool instead of tristate Signed-off-by: Huangjie --- drivers/dma/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 603395018b0..e60d7a8ab81 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -504,7 +504,7 @@ config PCH_DMA ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. config PHYTIUM_DDMA - tristate "Phytium PE220x DDMA support" + bool "Phytium PE220x DDMA support" depends on (ARCH_PHYTIUM || COMPILE_TEST) select DMA_ENGINE select DMA_VIRTUAL_CHANNELS -- Gitee From 66fc757abf3b6d979568d7fd38e91bdc5caef671 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Wed, 5 Jun 2024 11:02:08 +0800 Subject: [PATCH 67/71] arm64: phytium_defconfig: select CONFIG_PHYTIUM_DDMA as y Signed-off-by: Huangjie --- arch/arm64/configs/phytium_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 270afd2b791..2d66fa2829b 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -779,7 +779,7 @@ CONFIG_DMADEVICES=y CONFIG_BCM_SBA_RAID=m CONFIG_FSL_EDMA=y CONFIG_MV_XOR_V2=y -CONFIG_PHYTIUM_DDMA=m +CONFIG_PHYTIUM_DDMA=y CONFIG_PL330_DMA=y CONFIG_QCOM_HIDMA_MGMT=y CONFIG_QCOM_HIDMA=y -- Gitee From 35d95a14db98a88052ebdb79291d205905f540c5 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 6 Jun 2024 16:34:22 +0800 Subject: [PATCH 68/71] arm64: phytium_defconfig: select BT_HCIUART_3WIRE PhytiumPi need this config for bluetooth. Signed-off-by: liutianyu1250 --- arch/arm64/configs/phytium_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 2d66fa2829b..3f9d1b8130c 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -143,6 +143,7 @@ CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTUSB_MTK=y CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_QCA=y CONFIG_BT_HCIUART_MRVL=y -- Gitee From f5594211eb284de93866b805d1187fb73cf59d2d Mon Sep 17 00:00:00 2001 From: zuoqian Date: Thu, 13 Jun 2024 13:54:32 +0800 Subject: [PATCH 69/71] net: macb: phytium: set management port enable of NCR in the function macb_open If not set, macb will be unable to up phy link after waking up from sleep mode with the interface in a down state. Signed-off-by: zuoqian --- drivers/net/ethernet/cadence/macb_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 764505c9afb..cb04fbf8a43 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -3407,6 +3407,7 @@ static int macb_open(struct net_device *dev) napi_enable(&queue->napi_tx); } + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(MPE)); macb_init_hw(bp); err = phy_power_on(bp->sgmii_phy); -- Gitee From 93d6e3c597ffa7d9f9e9bbf37af98bbd6e005f37 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 13 Jun 2024 17:50:28 +0800 Subject: [PATCH 70/71] net: stmmac: phytium driver add pm support Test S3 with net device open will got this cut log. ... NETDEV WATCHDOG: eth0 (phytium-dwmac): transmit queue 0 timed out 8532ms WARNING: CPU: 2 PID: 0 at net/sched/sch_generic.c:525 dev_watchdog+0x234/0x23c ... Miss pm function in phytium_dwmac_driver. So add it. Signed-off-by: liutianyu1250 --- drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c index d31b8e870f6..6e8e44730be 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-phytium.c @@ -209,6 +209,7 @@ static struct platform_driver phytium_dwmac_driver = { .remove = phytium_dwmac_remove, .driver = { .name = "phytium-dwmac", + .pm = &stmmac_pltfr_pm_ops, .of_match_table = of_match_ptr(phytium_dwmac_of_match), .acpi_match_table = ACPI_PTR(phytium_dwmac_acpi_ids), }, -- Gitee From 2284f4f59f0147bc5d669d08682d250bdf77f494 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 13 Jun 2024 19:31:51 +0800 Subject: [PATCH 71/71] Phytium Embedded SDK v3.0 Signed-off-by: liutianyu1250 --- arch/arm64/configs/phytium_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 3f9d1b8130c..015369ac027 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="-phytium-embedded" +CONFIG_LOCALVERSION="-phytium-embedded-v3.0" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -- Gitee