From 2def37e23355897ebc7657e4a8e6051cfb2a250b 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 78180523c0..be7073a3e3 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 a593bed39731dca73a40d60ce147ba482d9f34f8 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 f04460ea14..2bfff87318 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 a789119e64..0fd77961c6 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 e26162e395..ddbe363bfa 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 5af8859ba6..30918bfe6f 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 d1c1a0de5f..e2b16275df 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 7f28d66673..797d7b4ee1 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 05d422d4a5..e176c334cb 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 c0621dce12..b4fd9ae0b6 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 5713c74170434c2839c86b1b31b79b7b909bafa5 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 84dca3695f..c444082e04 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 bcd6ab998d51babbbd1e8ff567dfd7a19e69ed08 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 0000000000..098dbd867a --- /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 2bfff87318..79e25d2719 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 fcb536a33d3ad3a005af1113aef503352fba964a 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 79e25d2719..e02a06d96a 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 025b6ee672..69b71c803e 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 b45c72a6a5..d3caedd416 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 0000000000..af6a729816 --- /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 408eab3bb217521445b10a44619df83f4a42a57e 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 ba0296bddd..44379f5589 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 e71e50c29a2319572f501dab4d9f57efc6e5362a 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 30918bfe6f..acd5951bf0 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 4b941cc0e8f40c4d020398c897396a4112a19423 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 c89251f359..00a773014f 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 ddcc441dc9411322d3047152010e05d68fb068eb 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 9997ce38ff..98ae864a82 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 a932a244de5d64fe2104c3aa89421a4e4e8fc780 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 26a6c75352..2f808b89e4 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 7a7c7d123fe9eb6a4b14d6896d2399331aede613 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 68254af262..c661a86ae2 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 611ae9345c23f1ed744f643f1d2d3e78648ecacf 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 7958531b0c..579e6bacc3 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 dfc17106ac1e321c3df530e01ed3ea2fbf857eb8 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 c65601bddc..8237c0051e 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 20266cb78b3143e0edf501f10c155b867967d1df 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 b5ed0650e2..dcf6c18def 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 989de98496268e4e60aa159c4469110701025bb2 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 acd5951bf0..b5e4ee3e9d 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 6c944fdd92dce2dac9f9165331515346578dc64a 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 874f6c5aa5..014af0162c 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 0f1327142d70192cc6eabdb160f88d078f514f67 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 d58db7afa3..0f86dc2399 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 3d45258278..b99d2b4980 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 98bb78caf7ca572df6e2016df11ad3ad1e62a088 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 b5f012619e..fead848224 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 ae2b3baa97da7b847e41847636566b3b823093dd 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 c09fcf5041..1eaddca021 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 a4d8437750de1d55b3c560131f3685796747fe35 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 44bf7a9822..3a5441dcc7 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 4c7fbd437f..a836921fb0 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 9b5ce4b1c4e8551d2098520e8afc2ed85328ef51 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 e02a06d96a..dbf220d4f5 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 3c431de863..cfaf68b2d3 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 0a18c8b714..25693b6339 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 54032b429b..6ef8acfe5c 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 8b8570c7e1..9b82c5c016 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 be7073a3e3..131baeacdc 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 f1f234b595..781a4fae52 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 f18feb0bef4216b257a29d176e7366c7025f3115 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 dbf220d4f5..d492a084d5 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 a930cea628..d31b8e870f 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 939b980ed66410aa0272d7c73903a330de197d95 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 dfdb5bf702..907396fd43 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 58307528917d8ff41e08df46ce1053c851e3009d 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 907396fd43..159e34708c 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 dd04993abe..11959e97e6 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 972a8536bc81c5fc2175ef770982d3245f68e44d 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 159e34708c..52bb3752de 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 76d9f48d3712b1ce1bb776e672d95aa472f7a0c1 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 52bb3752de..2d666ab283 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 99bd4b29b31d4ea617fe9f351cacbe4c0096e878 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 3967fe6a97..8cc80d1d10 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 bee85fc007..d84122f8ef 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 ef964406de066169f558b91b32e7de434bad3ca8 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 d84122f8ef..3fa8b2acc6 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 7cedd3040a4090ea09c8285b67c89712c7a6fd0f 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 3fa8b2acc6..0ac36260ce 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 d1649fe9bf0fbfe07b602cc337753c2f1e8755f9 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 dcf6c18def..86cd17120b 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 795c5209516167bcb9853d1ca4949be512d684f6 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 5cea3a283f..e533659930 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 d492a084d5..5a4dc4f7c1 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 a44507a40a36bd1c6fecce441b4ec2af5f90487a 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 5a4dc4f7c1..24b491bfa5 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 46297c1baa..d0b4577f17 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 1f68cdcd80..2dc7ea1118 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 e41c09c0b9..8adc1c6e10 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 4c2287b337..3203f606e1 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 40583f28d8..6f84743215 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 a3cbe23490..adce24d159 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 c4d2c844c1..616fddf207 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 eb6f8987a2..693d5408fe 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 8a54b106f91f789b09cdaa58b903291910439da7 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 315ad6b4b8..bc28ad8d45 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 068f02c0bdd2417d53092f46cbf1bc7a5bad76b7 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 6f84743215..567dfdc3d5 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 4ed20c21bc5699f0f1eb53d0fa59b128d4127eb5 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 3203f606e1..f94e0cf4eb 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 5aac502420..d9d750eee3 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 616fddf207..7d962076f7 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 114c6306fd..3d91ad68a5 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 a892258a60267b577c1b20a2cd02d6958cb97969 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 3d91ad68a5..e046c299da 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 f1a750a6d992910b79993f68f63e6e7a0bcc8e6c 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 4dca6c0231..20428a89b7 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 2f51fd5574fbcdeea0096fb74ec4b280d84c347e 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 fef637a140..c68a790ed4 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 f54d1bc6bfd7aa7360bbe4e965ef8c4a0dfe868d 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 74edbce232..6f334bb43f 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 08ac85517c9bf1515379f25ad890f735c8a22e0a 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 d0b4577f17..e1b91e6a2c 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 872e8c10eae9f556cda1ae26d3911ab0cb9d0c67 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 69b71c803e..1cbc7b48a0 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 d3caedd416..f21c95254a 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 968b9cff18..0000000000 --- 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 1a9731ca1e303be5a8cfbed90098d3d589cc082b 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 a836921fb0..f66fd22aa1 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 588820dc85765b3db7d0fe8d8f0f0850d2ecbf7e 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 f66fd22aa1..fd4256912b 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 7f6d917c2c4610974e32244213d72a544d13001d 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 3a5441dcc7..bff334e15c 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 fd4256912b..383a692fe3 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 d095f427f4d9ef21f2506d028621a5a073ed9e7e 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 383a692fe3..47cd9c2c81 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 9f9e2fbba23b293214c9478cb3beb19c7d1f6a1e 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 47cd9c2c81..764505c9af 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 9ff6ff6160bcd05dc293216146e2d7f28008db29 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 20428a89b7..f5d4a6945c 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 dd75405f60a5b85e69fa1d86e0368de9785c92b1 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 5bc57fa6dc..ffa4041525 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 05c9dfcaa23544053fe7c1d4c7fb167320e7c5f4 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 0000000000..07554cf843 --- /dev/null +++ b/arch/arm64/configs/phytium_optee.config @@ -0,0 +1,2 @@ +CONFIG_TEE=y +CONFIG_OPTEE=y -- Gitee From 832b4facea17793a148bcb4e01caa08a05287056 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 0ac36260ce..9119cdae1c 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 a0f6c49dd2a6ffc267b3189642d91b15ebcc593c 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 0818b9db10..c63abddd09 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 4d121e034643f26ce7ae7f03ddf8cc3b65d53a96 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 aedbf2696e..85ff8e5667 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 4c3c99e7eda44976c5f0eb70a3572333056d74a5 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 b5e4ee3e9d..b067f8b4dd 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 49d42528e382df04a9c21e50971157c9098f7633 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 87383c0542..6a16007c60 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 af3e33f34fd26deb2fd50c80e8a215729fe6a8b2 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 b067f8b4dd..4a938fea36 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 fbe30a2df9..90f51b9ee1 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 a78386a499744c203995db62adc6d2caae6efde3 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 a99b53d442..d8d68f1601 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 f9bfa7ca0008c16d92659e05ba25d916ad9a373b 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 2c1fb2dabd..0cae5746f5 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 9be6e362a8b4ed1eb12e8bd676d8ccfa7ef674a9 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 e6ab1ac6d7..a018851109 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 e75842f5a73f684e15bb48e8064ddd498d46d2c3 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 4a33d2e47f..63673005c2 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 128e75a81b..37ef80c909 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 40359e07794532164886ffd3423464e420df62b8 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 adf224618a..5f3a3a88c3 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 92e82b15955391a21af1428ec2bfe70ca4101d4a 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 7a5cbdc31e..e2c7d9f876 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 16dee7ef193d28eb066cd0368fe0a6f3fc2ec74c 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 298663b035..0c1c1ff310 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 47df01f268b35521fd7896535609c4056256e1b8 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 0f86dc2399..8d58eaa99d 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 e060118e9466c44dbd31d82c80b467ace99a4201 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 015976378c..5c1f8e2e81 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 44b8aab0ac79b15436e2ba7681e16112014b560e 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 5c1f8e2e81..768236d994 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 9689fa8bb9b919b2027cca59e15d499ccebbfe23 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 603395018b..e60d7a8ab8 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 58afce0e4de04a58b0740b5e4ca56bb8478bd456 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 65142960a5..45b14a847d 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -763,7 +763,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 be9ea45ea864fedc37dd00dd99b8c0dfc934e25d 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 45b14a847d..8c4f8360bc 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -141,6 +141,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 cca87b03959765daf668f59d1090196e08b65605 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 764505c9af..cb04fbf8a4 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 e4084ab6219ff1e5b2ad5cc68b58be491b3f448f 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 d31b8e870f..6e8e44730b 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 3011800373e182525b712ddf1c6b6c8c0d221eae 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 8c4f8360bc..c0b8ebe629 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