diff --git a/arch/arm64/boot/dts/phytium/e2000q-miniitx-board.dts b/arch/arm64/boot/dts/phytium/e2000q-miniitx-board.dts index 9015eae866dce1082c91d269f83bb5bc6e27fc73..4ef260940fd22cc03d07eb7008a102d3758a42a9 100644 --- a/arch/arm64/boot/dts/phytium/e2000q-miniitx-board.dts +++ b/arch/arm64/boot/dts/phytium/e2000q-miniitx-board.dts @@ -9,6 +9,7 @@ /dts-v1/; /memreserve/ 0x80000000 0x10000; +/memreserve/ 0xf4000000 0x4000000; #include "pe2204.dtsi" @@ -213,6 +214,8 @@ &macb2 { }; &dc0 { + reg = <0x0 0x32000000 0x0 0x8000>, + <0x0 0xf4000000 0x0 0x4000000>; // (optional) pipe_mask = [03]; edp_mask = [00]; status = "okay"; diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 4592782772203cbd940d31ebc750dc2341476403..9731d95d95504e0f2d43a4b90b7bdac8d9def08d 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="-phytium-embeded-2023-v1.0-GA" +CONFIG_LOCALVERSION="-phytium-embeded-v1.1" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y diff --git a/drivers/net/can/phytium/phytium_can.c b/drivers/net/can/phytium/phytium_can.c index e03e0c0d41d8a73b0fba7a925d3ea27e97809130..e94a7c66ed364e87f87fb5a8f06d680c7259942b 100644 --- a/drivers/net/can/phytium/phytium_can.c +++ b/drivers/net/can/phytium/phytium_can.c @@ -437,6 +437,7 @@ static int phytium_can_poll(struct napi_struct *napi, int quota) struct net_device *dev = napi->dev; struct phytium_can_dev *cdev = netdev_priv(dev); int work_done; + unsigned long flags; netdev_dbg(dev, "The receive processing is going on !\n"); @@ -447,7 +448,9 @@ static int phytium_can_poll(struct napi_struct *napi, int quota) */ if (work_done >= 0 && work_done < quota) { napi_complete_done(napi, work_done); - phytium_can_enable_all_interrupts(cdev); + spin_lock_irqsave(&cdev->lock, flags); + phytium_can_set_reg_bits(cdev, CAN_INTR, INTR_REIE); + spin_unlock_irqrestore(&cdev->lock, flags); } return work_done; @@ -465,8 +468,6 @@ static void phytium_can_write_frame(struct phytium_can_dev *cdev) data_len = can_len2dlc(cf->len); cdev->tx_skb = NULL; - phytium_can_clr_reg_bits(cdev, CAN_CTRL, CTRL_XFER); - /* Watch carefully on the bit sequence */ if (cf->can_id & CAN_EFF_FLAG) { /* Extended CAN ID format */ @@ -548,15 +549,10 @@ static void phytium_can_write_frame(struct phytium_can_dev *cdev) } stats->tx_bytes += cf->len; - can_put_echo_skb(skb, dev, cdev->tx_head % cdev->tx_max); - cdev->tx_head++; - - netif_stop_queue(dev); - /* triggers tranmission */ - phytium_can_set_reg_bits(cdev, CAN_CTRL, CTRL_TXREQ | CTRL_XFER); - + stats->tx_packets++; netdev_dbg(dev, "Trigger send message!\n"); - + can_put_echo_skb(skb, dev, 0); + can_get_echo_skb(dev, 0); return; } @@ -564,22 +560,28 @@ static netdev_tx_t phytium_can_tx_handler(struct phytium_can_dev *cdev) { struct net_device *dev = cdev->net; u32 tx_fifo_used; + unsigned long flags; - /* Check if the TX buffer is full */ - tx_fifo_used = (phytium_can_read(cdev, CAN_FIFO_CNT) & FIFO_CNT_TFN) >> 16; - if (tx_fifo_used == cdev->tx_max) { - netif_stop_queue(dev); - netdev_err(dev, "BUG!, TX FIFO full when queue awake!\n"); - return NETDEV_TX_BUSY; - } + phytium_can_write_frame(cdev); - if (cdev->tx_head == cdev->tx_tail) { - cdev->tx_head = 0; - cdev->tx_tail = 0; + /* Check if the TX buffer is full */ + tx_fifo_used = 4 * ((phytium_can_read(cdev, CAN_FIFO_CNT) & FIFO_CNT_TFN) >> 16); + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { + if (CAN_FIFO_BYTE_LEN - tx_fifo_used <= KEEP_CANFD_FIFO_MIN_LEN) { + netif_stop_queue(dev); + spin_lock_irqsave(&cdev->lock, flags); + cdev->is_stop_queue_flag = STOP_QUEUE_TRUE; + spin_unlock_irqrestore(&cdev->lock, flags); + } + } else { + if (CAN_FIFO_BYTE_LEN - tx_fifo_used <= KEEP_CAN_FIFO_MIN_LEN) { + netif_stop_queue(dev); + spin_lock_irqsave(&cdev->lock, flags); + cdev->is_stop_queue_flag = STOP_QUEUE_TRUE; + spin_unlock_irqrestore(&cdev->lock, flags); + } } - phytium_can_write_frame(cdev); - return NETDEV_TX_OK; } @@ -592,19 +594,29 @@ static void phytium_can_tx_interrupt(struct net_device *ndev, u32 isr) { struct phytium_can_dev *cdev = netdev_priv(ndev); struct net_device_stats *stats = &ndev->stats; + u32 tx_fifo_used = 0; - while ((cdev->tx_head - cdev->tx_tail > 0) && (isr & INTR_TEIS)) { - phytium_can_set_reg_bits(cdev, CAN_INTR, INTR_TEIC | INTR_REIC); - can_get_echo_skb(ndev, cdev->tx_tail % cdev->tx_max); - cdev->tx_tail++; - stats->tx_packets++; - isr = (phytium_can_read(cdev, CAN_INTR) & INTR_STATUS_MASK); + if (isr & INTR_TEIS) { + phytium_can_set_reg_bits(cdev, CAN_INTR, INTR_TEIC); } + /* Check if the TX buffer is full */ + if (cdev->is_stop_queue_flag) { + tx_fifo_used = 4 * ((phytium_can_read(cdev, CAN_FIFO_CNT) & FIFO_CNT_TFN) >> 16); + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { + if (CAN_FIFO_BYTE_LEN - tx_fifo_used > KEEP_CANFD_FIFO_MIN_LEN) { + netif_wake_queue(ndev); + cdev->is_stop_queue_flag = STOP_QUEUE_FALSE; + } + } else { + if (CAN_FIFO_BYTE_LEN - tx_fifo_used > KEEP_CAN_FIFO_MIN_LEN) { + netif_wake_queue(ndev); + cdev->is_stop_queue_flag = STOP_QUEUE_FALSE; + } + } + } netdev_dbg(ndev, "Finish transform packets %lu\n", stats->tx_packets); - netdev_dbg(ndev, "\n-------------------\n"); can_led_event(ndev, CAN_LED_EVENT_TX); - netif_wake_queue(ndev); } static void phytium_can_err_interrupt(struct net_device *ndev, u32 isr) @@ -705,7 +717,7 @@ static irqreturn_t phytium_can_isr(int irq, void *dev_id) isr = phytium_can_read(cdev, CAN_INTR) & INTR_STATUS_MASK; if (!isr) return IRQ_NONE; - + spin_lock(&cdev->lock); /* Check for FIFO full interrupt and alarm */ if ((isr & INTR_RFIS)) { netdev_dbg(dev, "rx_fifo is full!.\n"); @@ -722,6 +734,7 @@ static irqreturn_t phytium_can_isr(int irq, void *dev_id) phytium_can_set_reg_bits(cdev, CAN_INTR, (INTR_EIC | INTR_RFIC | INTR_BOIC)); phytium_can_set_reg_bits(cdev, CAN_INTR, INTR_EIE | INTR_BOIE); + spin_unlock(&cdev->lock); return IRQ_HANDLED; } @@ -736,7 +749,7 @@ static irqreturn_t phytium_can_isr(int irq, void *dev_id) phytium_can_set_reg_bits(cdev, CAN_INTR, INTR_REIC); napi_schedule(&cdev->napi); } - + spin_unlock(&cdev->lock); return IRQ_HANDLED; } @@ -864,7 +877,7 @@ static void phytium_can_stop(struct net_device *dev) /* Disable all interrupts */ phytium_can_disable_all_interrupt(cdev); - + /* Disable transfer and switch to receive-only mode */ ctrl = phytium_can_read(cdev, CAN_CTRL); ctrl &= ~(CTRL_XFER | CTRL_TXREQ); @@ -936,6 +949,7 @@ static int phytium_can_open(struct net_device *dev) can_led_event(dev, CAN_LED_EVENT_OPEN); napi_enable(&cdev->napi); + cdev->is_stop_queue_flag = STOP_QUEUE_FALSE; netif_start_queue(dev); return 0; @@ -1021,7 +1035,7 @@ static int phytium_can_dev_setup(struct phytium_can_dev *cdev) cdev->can.ctrlmode = CAN_CTRLMODE_FD; cdev->can.data_bittiming_const = cdev->bit_timing; } - + spin_lock_init(&cdev->lock); return 0; } diff --git a/drivers/net/can/phytium/phytium_can.h b/drivers/net/can/phytium/phytium_can.h index 3f125548c4a6f1dc20d90076102b8a49f1b1d96e..e8e5cff92d8eefd9ba7d255155235ae309e79d83 100644 --- a/drivers/net/can/phytium/phytium_can.h +++ b/drivers/net/can/phytium/phytium_can.h @@ -23,6 +23,12 @@ #include #include +#define KEEP_CAN_FIFO_MIN_LEN 16 +#define KEEP_CANFD_FIFO_MIN_LEN 128 +#define CAN_FIFO_BYTE_LEN 256 +#define STOP_QUEUE_TRUE 1 +#define STOP_QUEUE_FALSE 0 + enum phytium_can_ip_type { PHYTIUM_CAN = 0, PHYTIUM_CANFD, @@ -35,9 +41,6 @@ struct phytium_can_devtype { struct phytium_can_dev { struct can_priv can; - unsigned int tx_head; - unsigned int tx_tail; - unsigned int tx_max; struct napi_struct napi; struct net_device *net; struct device *dev; @@ -46,11 +49,12 @@ struct phytium_can_dev { struct sk_buff *tx_skb; const struct can_bittiming_const *bit_timing; - + spinlock_t lock; int fdmode; u32 isr; u32 tx_fifo_depth; - + unsigned int is_stop_queue_flag; + struct completion comp; void __iomem *base; }; diff --git a/drivers/net/can/phytium/phytium_can_platform.c b/drivers/net/can/phytium/phytium_can_platform.c index 3a4f4b47c9b60dc827bf0c304f684d181efeba5c..ce479af1116242d06afe61355538c571afb0f8ed 100644 --- a/drivers/net/can/phytium/phytium_can_platform.c +++ b/drivers/net/can/phytium/phytium_can_platform.c @@ -135,9 +135,6 @@ static int phytium_can_plat_probe(struct platform_device *pdev) } cdev->tx_fifo_depth = tx_fifo_depth; - cdev->tx_head = 0; - cdev->tx_tail = 0; - cdev->tx_max = tx_fifo_depth; if (devtype->cantype == PHYTIUM_CANFD) cdev->fdmode = 1; diff --git a/drivers/spi/spi-phytium-pci.c b/drivers/spi/spi-phytium-pci.c index a6ed0bb4492cad93733f3b9278197b51bc197c7b..ab312ef1024854c1a9162e1e9826490509391671 100644 --- a/drivers/spi/spi-phytium-pci.c +++ b/drivers/spi/spi-phytium-pci.c @@ -88,16 +88,14 @@ static void phytium_spi_pci_remove(struct pci_dev *pdev) #ifdef CONFIG_PM_SLEEP static int spi_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct phytium_spi *fts = spi_master_get_devdata(master); + struct phytium_spi *fts = dev_get_drvdata(dev); return phytium_spi_suspend_host(fts); } static int spi_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct phytium_spi *fts = spi_master_get_devdata(master); + struct phytium_spi *fts = dev_get_drvdata(dev); return phytium_spi_resume_host(fts); } diff --git a/sound/pci/hda/hda_phytium.c b/sound/pci/hda/hda_phytium.c index 5d3fa387b1f5946e7ddc18a520b0f5d090ff15fb..fe4f91f5b461da500cbd7c240b7456aa7efcded3 100644 --- a/sound/pci/hda/hda_phytium.c +++ b/sound/pci/hda/hda_phytium.c @@ -829,9 +829,6 @@ static int azx_first_init(struct azx *chip) bus->cmd_resend = 1; - if (azx_acquire_irq(chip, 0) < 0) - return -EBUSY; - synchronize_irq(bus->irq); gcap = azx_readw(chip, GCAP); @@ -895,6 +892,9 @@ static int azx_first_init(struct azx *chip) return -ENODEV; } + if (azx_acquire_irq(chip, 0) < 0) + return -EBUSY; + strcpy(card->driver, "ft-hda"); strcpy(card->shortname, "ft-hda"); snprintf(card->longname, sizeof(card->longname),