* OMAP4430 SDP with KS8851: very slow networking @ 2018-12-06 13:22 Russell King - ARM Linux 2018-12-06 16:31 ` Tony Lindgren 0 siblings, 1 reply; 9+ messages in thread From: Russell King - ARM Linux @ 2018-12-06 13:22 UTC (permalink / raw) To: linux-arm-kernel, linux-omap, netdev, Tony Lindgren Hi, I'm experiencing very slow networking on my OMAP4430 SDP board, which uses the SPI ethernet chip KS8851. The initial symptom I noticed is that tftping the 3MB kernel image inside Linux takes more than 5 minutes. Running tcpdump on the tftp server shows: 13:13:29.018377 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.020683 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.022280 IP 192.168.0.4.40620 > 192.168.1.189.45542: UDP, length 516 13:13:29.078391 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.080696 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.082291 IP 192.168.0.4.40620 > 192.168.1.189.45542: UDP, length 516 13:13:29.138377 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.140563 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.142205 IP 192.168.0.4.40620 > 192.168.1.189.45542: UDP, length 516 13:13:29.198365 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.200709 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.202292 IP 192.168.0.4.40620 > 192.168.1.189.45542: UDP, length 516 13:13:29.258375 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.260708 IP 192.168.1.189.45542 > 192.168.0.4.40620: UDP, length 4 13:13:29.262292 IP 192.168.0.4.40620 > 192.168.1.189.45542: UDP, length 516 which is about 512 bytes every 60ms. The two length 4 UDPs are the ACK packets - one of which is a repeated transmission for each packet. I also see NFS timing out. pings also have weirdness: root@omap-4430sdp:~# ping -c 10 192.168.0.4 PING 192.168.0.4 (192.168.0.4): 56 data bytes 64 bytes from 192.168.0.4: seq=0 ttl=64 time=107.635 ms 64 bytes from 192.168.0.4: seq=1 ttl=64 time=1011.689 ms 64 bytes from 192.168.0.4: seq=2 ttl=64 time=5.157 ms 64 bytes from 192.168.0.4: seq=3 ttl=64 time=1021.820 ms 64 bytes from 192.168.0.4: seq=4 ttl=64 time=4.395 ms 64 bytes from 192.168.0.4: seq=5 ttl=64 time=4.669 ms 64 bytes from 192.168.0.4: seq=6 ttl=64 time=371.735 ms 64 bytes from 192.168.0.4: seq=7 ttl=64 time=882.598 ms 64 bytes from 192.168.0.4: seq=8 ttl=64 time=31.372 ms 64 bytes from 192.168.0.4: seq=9 ttl=64 time=2010.772 ms --- 192.168.0.4 ping statistics --- 10 packets transmitted, 10 packets received, 0% packet loss round-trip min/avg/max = 4.395/545.184/2010.772 ms If I ping the board remotely: $ ping -i .2 192.168.1.189 PING 192.168.1.189 (192.168.1.189) 56(84) bytes of data. 64 bytes from 192.168.1.189: icmp_req=1 ttl=64 time=2033 ms 64 bytes from 192.168.1.189: icmp_req=2 ttl=64 time=1825 ms 64 bytes from 192.168.1.189: icmp_req=3 ttl=64 time=1616 ms 64 bytes from 192.168.1.189: icmp_req=4 ttl=64 time=1417 ms 64 bytes from 192.168.1.189: icmp_req=5 ttl=64 time=1218 ms 64 bytes from 192.168.1.189: icmp_req=6 ttl=64 time=1018 ms 64 bytes from 192.168.1.189: icmp_req=7 ttl=64 time=819 ms 64 bytes from 192.168.1.189: icmp_req=8 ttl=64 time=610 ms 64 bytes from 192.168.1.189: icmp_req=9 ttl=64 time=411 ms 64 bytes from 192.168.1.189: icmp_req=10 ttl=64 time=202 ms 64 bytes from 192.168.1.189: icmp_req=11 ttl=64 time=4.46 ms 64 bytes from 192.168.1.189: icmp_req=12 ttl=64 time=263 ms 64 bytes from 192.168.1.189: icmp_req=13 ttl=64 time=54.5 ms 64 bytes from 192.168.1.189: icmp_req=14 ttl=64 time=1399 ms 64 bytes from 192.168.1.189: icmp_req=15 ttl=64 time=1199 ms 64 bytes from 192.168.1.189: icmp_req=16 ttl=64 time=990 ms 64 bytes from 192.168.1.189: icmp_req=17 ttl=64 time=781 ms 64 bytes from 192.168.1.189: icmp_req=18 ttl=64 time=572 ms 64 bytes from 192.168.1.189: icmp_req=19 ttl=64 time=372 ms 64 bytes from 192.168.1.189: icmp_req=20 ttl=64 time=163 ms ^C --- 192.168.1.189 ping statistics --- 22 packets transmitted, 20 received, 9% packet loss, time 4302ms rtt min/avg/max/mdev = 4.468/848.854/2033.873/592.100 ms, pipe 10 It looks very much like a receive problem - in that the board is not always aware of a packet having been received until it attempts to transmit (eg, in the case of TFTP, when it re-sends the ACK after a receive timeout, it _then_ notices that there's a packet waiting.) I'm not quite sure when this cropped up as I no longer regularly update and run my nightly boot tests, but I think 4.18 was fine. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up According to speedtest.net: 11.9Mbps down 500kbps up ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-06 13:22 OMAP4430 SDP with KS8851: very slow networking Russell King - ARM Linux @ 2018-12-06 16:31 ` Tony Lindgren 2018-12-06 18:08 ` Russell King - ARM Linux 0 siblings, 1 reply; 9+ messages in thread From: Tony Lindgren @ 2018-12-06 16:31 UTC (permalink / raw) To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, netdev Hi, * Russell King - ARM Linux <linux@armlinux.org.uk> [181206 13:23]: > It looks very much like a receive problem - in that the board is not > always aware of a packet having been received until it attempts to > transmit (eg, in the case of TFTP, when it re-sends the ACK after a > receive timeout, it _then_ notices that there's a packet waiting.) > > I'm not quite sure when this cropped up as I no longer regularly > update and run my nightly boot tests, but I think 4.18 was fine. Sounds like it's some gpio or PM related issue. If it's not caused by commit b764a5863fd8 ("gpio: omap: Remove custom PM calls and use cpu_pm instead"), then maybe the changes to probe devices with ti-sysc interconnect target module driver caused it. Below is a revert for mcspi that would help in that case. Also I guess it could be caused by drivers/spi/spi-omap2-mcspi.c changes since v4.18. Care to post output of /sys/kernel/debug/pm_debug/count for a working and non-working kernels? Regards, Tony 8< ------------------- diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi --- a/arch/arm/boot/dts/omap4-l4.dtsi +++ b/arch/arm/boot/dts/omap4-l4.dtsi @@ -2050,25 +2050,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x98000 0x1000>; - - mcspi1: spi@0 { - compatible = "ti,omap4-mcspi"; - reg = <0x0 0x200>; - interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - ti,spi-num-cs = <4>; - dmas = <&sdma 35>, - <&sdma 36>, - <&sdma 37>, - <&sdma 38>, - <&sdma 39>, - <&sdma 40>, - <&sdma 41>, - <&sdma 42>; - dma-names = "tx0", "rx0", "tx1", "rx1", - "tx2", "rx2", "tx3", "rx3"; - }; + status = "disabled"; }; target-module@9a000 { /* 0x4809a000, ap 51 2c.0 */ @@ -2089,20 +2071,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x9a000 0x1000>; - - mcspi2: spi@0 { - compatible = "ti,omap4-mcspi"; - reg = <0x0 0x200>; - interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - ti,spi-num-cs = <2>; - dmas = <&sdma 43>, - <&sdma 44>, - <&sdma 45>, - <&sdma 46>; - dma-names = "tx0", "rx0", "tx1", "rx1"; - }; + status = "disabled"; }; target-module@9c000 { /* 0x4809c000, ap 53 36.0 */ @@ -2290,17 +2259,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xb8000 0x1000>; - - mcspi3: spi@0 { - compatible = "ti,omap4-mcspi"; - reg = <0x0 0x200>; - interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - ti,spi-num-cs = <2>; - dmas = <&sdma 15>, <&sdma 16>; - dma-names = "tx0", "rx0"; - }; + status = "disabled"; }; target-module@ba000 { /* 0x480ba000, ap 71 32.0 */ @@ -2321,17 +2280,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xba000 0x1000>; - - mcspi4: spi@0 { - compatible = "ti,omap4-mcspi"; - reg = <0x0 0x200>; - interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - ti,spi-num-cs = <1>; - dmas = <&sdma 70>, <&sdma 71>; - dma-names = "tx0", "rx0"; - }; + status = "disabled"; }; target-module@d1000 { /* 0x480d1000, ap 73 44.0 */ diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -193,6 +193,66 @@ #gpio-cells = <2>; }; + mcspi1: spi@48098000 { + compatible = "ti,omap4-mcspi"; + reg = <0x48098000 0x200>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi1"; + ti,spi-num-cs = <4>; + dmas = <&sdma 35>, + <&sdma 36>, + <&sdma 37>, + <&sdma 38>, + <&sdma 39>, + <&sdma 40>, + <&sdma 41>, + <&sdma 42>; + dma-names = "tx0", "rx0", "tx1", "rx1", + "tx2", "rx2", "tx3", "rx3"; + }; + + mcspi2: spi@4809a000 { + compatible = "ti,omap4-mcspi"; + reg = <0x4809a000 0x200>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi2"; + ti,spi-num-cs = <2>; + dmas = <&sdma 43>, + <&sdma 44>, + <&sdma 45>, + <&sdma 46>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + }; + + mcspi3: spi@480b8000 { + compatible = "ti,omap4-mcspi"; + reg = <0x480b8000 0x200>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi3"; + ti,spi-num-cs = <2>; + dmas = <&sdma 15>, <&sdma 16>; + dma-names = "tx0", "rx0"; + }; + + mcspi4: spi@480ba000 { + compatible = "ti,omap4-mcspi"; + reg = <0x480ba000 0x200>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi4"; + ti,spi-num-cs = <1>; + dmas = <&sdma 70>, <&sdma 71>; + dma-names = "tx0", "rx0"; + }; + + mmu_dsp: mmu@4a066000 { compatible = "ti,omap4-iommu"; reg = <0x4a066000 0x100>; -- 2.19.2 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-06 16:31 ` Tony Lindgren @ 2018-12-06 18:08 ` Russell King - ARM Linux 2018-12-06 22:14 ` Tony Lindgren 0 siblings, 1 reply; 9+ messages in thread From: Russell King - ARM Linux @ 2018-12-06 18:08 UTC (permalink / raw) To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, netdev On Thu, Dec 06, 2018 at 08:31:54AM -0800, Tony Lindgren wrote: > Hi, > > * Russell King - ARM Linux <linux@armlinux.org.uk> [181206 13:23]: > > It looks very much like a receive problem - in that the board is not > > always aware of a packet having been received until it attempts to > > transmit (eg, in the case of TFTP, when it re-sends the ACK after a > > receive timeout, it _then_ notices that there's a packet waiting.) > > > > I'm not quite sure when this cropped up as I no longer regularly > > update and run my nightly boot tests, but I think 4.18 was fine. > > Sounds like it's some gpio or PM related issue. If it's not caused > by commit b764a5863fd8 ("gpio: omap: Remove custom PM calls and > use cpu_pm instead"), then maybe the changes to probe devices > with ti-sysc interconnect target module driver caused it. Below > is a revert for mcspi that would help in that case. In the interests of keeping the mailing list record up to date, with the following: 850d434ea37b ("gpio: omap: Remove set but not used variable 'dev'") c4791bc6e3a6 ("gpio: omap: drop omap_gpio_list") 467480738d0b ("gpio: omap: get rid of the conditional PM runtime calls") 5284521a290e ("gpio: omap: Get rid of pm_runtime_irq_safe()") b764a5863fd8 ("gpio: omap: Remove custom PM calls and use cpu_pm instead") reverted, the problem is still there. Revert: ec0daae685b2 ("gpio: omap: Add level wakeup handling for omap4 based SoCs") on top, and networking returns to normal. So it appears to be this last commit causing the issue. With that and b764a5863fd8 applied, it still misbehaves. Then, poking at the OMAP4_GPIO_IRQWAKEN0 register, changing it from 0 to 4 with devmem2 restores normal behaviour - ping times are normal and NFS is happy. # devmem2 0x48055044 w 4 (slightly more complex for me as its via NFS and needs different C libraries from the ones on the rootfs.) Given that this GPIO device is not runtime suspended, and is permanently active (which is what I think we expect, given that it has an IRQ claimed against it) does the hardware still attempt to idle the GPIO block - if so, could that be why we need to program the wakeup register, so the GPIO block signals that it's active? -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up According to speedtest.net: 11.9Mbps down 500kbps up ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-06 18:08 ` Russell King - ARM Linux @ 2018-12-06 22:14 ` Tony Lindgren 2018-12-07 18:00 ` Russell King - ARM Linux 0 siblings, 1 reply; 9+ messages in thread From: Tony Lindgren @ 2018-12-06 22:14 UTC (permalink / raw) To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap, netdev * Russell King - ARM Linux <linux@armlinux.org.uk> [181206 18:08]: > reverted, the problem is still there. Revert: > > ec0daae685b2 ("gpio: omap: Add level wakeup handling for omap4 based SoCs") > > on top, and networking returns to normal. So it appears to be this > last commit causing the issue. > > With that and b764a5863fd8 applied, it still misbehaves. Then, poking > at the OMAP4_GPIO_IRQWAKEN0 register, changing it from 0 to 4 with > devmem2 restores normal behaviour - ping times are normal and NFS is > happy. > > # devmem2 0x48055044 w 4 OK thanks. > Given that this GPIO device is not runtime suspended, and is > permanently active (which is what I think we expect, given that it > has an IRQ claimed against it) does the hardware still attempt to > idle the GPIO block - if so, could that be why we need to program > the wakeup register, so the GPIO block signals that it's active? Yes we now idle non-irq GPIOs only from CPU_CLUSTER_PM_ENTER as the selected cpuidle state triggers the domain transitions with WFI. And that's why runtime_suspended_time does not increase for a GPIO instance with IRQs. I can reproduce the long ping latencies on duovero smsc connected to gpio_44, I'll try to debug it more. Regards, Tony ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-06 22:14 ` Tony Lindgren @ 2018-12-07 18:00 ` Russell King - ARM Linux 2018-12-07 18:14 ` Tony Lindgren 0 siblings, 1 reply; 9+ messages in thread From: Russell King - ARM Linux @ 2018-12-07 18:00 UTC (permalink / raw) To: Tony Lindgren; +Cc: linux-arm-kernel, linux-omap, netdev Hi Tony, You know most of what's been going on from IRC, but here's the patch which gets me: 1) working interrupts for networking 2) solves the stuck-wakeup problem It also contains some of the debug bits I added. I think what this means is that we should strip out ec0daae685b2 ("gpio: omap: Add level wakeup handling for omap4 based SoCs"). diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 3d021f648c5d..528ffd1b9832 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -11,7 +11,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#define DEBUG #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -366,10 +366,14 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, trigger & IRQ_TYPE_LEVEL_LOW); omap_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit, trigger & IRQ_TYPE_LEVEL_HIGH); + /* + * We need the edge detect enabled for the idle mode detection + * to function on OMAP4430. + */ omap_gpio_rmw(base, bank->regs->risingdetect, gpio_bit, - trigger & IRQ_TYPE_EDGE_RISING); + trigger & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)); omap_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit, - trigger & IRQ_TYPE_EDGE_FALLING); + trigger & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)); bank->context.leveldetect0 = readl_relaxed(bank->base + bank->regs->leveldetect0); @@ -910,14 +914,16 @@ static void omap_gpio_unmask_irq(struct irq_data *d) if (trigger) omap_set_gpio_triggering(bank, offset, trigger); + omap_set_gpio_irqenable(bank, offset, 1); + /* For level-triggered GPIOs, the clearing must be done after - * the HW source is cleared, thus after the handler has run */ - if (bank->level_mask & BIT(offset)) { - omap_set_gpio_irqenable(bank, offset, 0); + * the HW source is cleared, thus after the handler has run. + * OMAP4 needs this done _after_ enabing the interrupt to clear + * the wakeup status. + */ + if (bank->level_mask & BIT(offset)) omap_clear_gpio_irqstatus(bank, offset); - } - omap_set_gpio_irqenable(bank, offset, 1); raw_spin_unlock_irqrestore(&bank->lock, flags); } @@ -1520,6 +1526,10 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) struct device *dev = bank->chip.parent; u32 l1 = 0, l2 = 0; + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); + if (bank->funcs.idle_enable_level_quirk) bank->funcs.idle_enable_level_quirk(bank); @@ -1553,6 +1563,10 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) bank->get_context_loss_count(dev); omap_gpio_dbck_disable(bank); + + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); } static void omap_gpio_init_context(struct gpio_bank *p); @@ -1563,6 +1577,10 @@ static void omap_gpio_unidle(struct gpio_bank *bank) u32 l = 0, gen, gen0, gen1; int c; + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); + /* * On the first resume during the probe, the context has not * been initialised and so initialise it now. Also initialise @@ -1648,6 +1666,10 @@ static void omap_gpio_unidle(struct gpio_bank *bank) } bank->workaround_enabled = false; + + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); } static void omap_gpio_init_context(struct gpio_bank *p) @@ -1720,6 +1742,7 @@ static int __maybe_unused omap_gpio_runtime_suspend(struct device *dev) error = -EBUSY; goto unlock; } + dev_dbg(dev, "%s()\n", __func__); omap_gpio_idle(bank, true); bank->is_suspended = true; unlock: @@ -1741,6 +1764,7 @@ static int __maybe_unused omap_gpio_runtime_resume(struct device *dev) error = -EBUSY; goto unlock; } + dev_dbg(dev, "%s()\n", __func__); omap_gpio_unidle(bank); bank->is_suspended = false; unlock: @@ -1827,8 +1851,8 @@ static const struct omap_gpio_platform_data omap4_pdata = { .regs = &omap4_gpio_regs, .bank_width = 32, .dbck_flag = true, - .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER | - OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN, + .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER /* | + OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN */, }; static const struct of_device_id omap_gpio_match[] = { -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up According to speedtest.net: 11.9Mbps down 500kbps up ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-07 18:00 ` Russell King - ARM Linux @ 2018-12-07 18:14 ` Tony Lindgren 2018-12-07 19:03 ` Tony Lindgren 0 siblings, 1 reply; 9+ messages in thread From: Tony Lindgren @ 2018-12-07 18:14 UTC (permalink / raw) To: Russell King - ARM Linux Cc: netdev, linux-omap, linux-arm-kernel, Grygorii Strashko Hi, * Russell King - ARM Linux <linux@armlinux.org.uk> [181207 18:01]: > Hi Tony, > > You know most of what's been going on from IRC, but here's the patch > which gets me: > > 1) working interrupts for networking > 2) solves the stuck-wakeup problem > > It also contains some of the debug bits I added. This is excellent news :) Will test today. > I think what this means is that we should strip out ec0daae685b2 > ("gpio: omap: Add level wakeup handling for omap4 based SoCs"). Yes the only reason for the wakeup quirk was the stuck wakeup state seen on omap4, it can be just dropped if this works. Adding Grygorii to Cc too. Regards, Tony > diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c > index 3d021f648c5d..528ffd1b9832 100644 > --- a/drivers/gpio/gpio-omap.c > +++ b/drivers/gpio/gpio-omap.c > @@ -11,7 +11,7 @@ > * it under the terms of the GNU General Public License version 2 as > * published by the Free Software Foundation. > */ > - > +#define DEBUG > #include <linux/init.h> > #include <linux/module.h> > #include <linux/interrupt.h> > @@ -366,10 +366,14 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, > trigger & IRQ_TYPE_LEVEL_LOW); > omap_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit, > trigger & IRQ_TYPE_LEVEL_HIGH); > + /* > + * We need the edge detect enabled for the idle mode detection > + * to function on OMAP4430. > + */ > omap_gpio_rmw(base, bank->regs->risingdetect, gpio_bit, > - trigger & IRQ_TYPE_EDGE_RISING); > + trigger & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)); > omap_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit, > - trigger & IRQ_TYPE_EDGE_FALLING); > + trigger & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)); > > bank->context.leveldetect0 = > readl_relaxed(bank->base + bank->regs->leveldetect0); > @@ -910,14 +914,16 @@ static void omap_gpio_unmask_irq(struct irq_data *d) > if (trigger) > omap_set_gpio_triggering(bank, offset, trigger); > > + omap_set_gpio_irqenable(bank, offset, 1); > + > /* For level-triggered GPIOs, the clearing must be done after > - * the HW source is cleared, thus after the handler has run */ > - if (bank->level_mask & BIT(offset)) { > - omap_set_gpio_irqenable(bank, offset, 0); > + * the HW source is cleared, thus after the handler has run. > + * OMAP4 needs this done _after_ enabing the interrupt to clear > + * the wakeup status. > + */ > + if (bank->level_mask & BIT(offset)) > omap_clear_gpio_irqstatus(bank, offset); > - } > > - omap_set_gpio_irqenable(bank, offset, 1); > raw_spin_unlock_irqrestore(&bank->lock, flags); > } > > @@ -1520,6 +1526,10 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) > struct device *dev = bank->chip.parent; > u32 l1 = 0, l2 = 0; > > + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, > + bank->context.leveldetect0, bank->context.leveldetect1, > + bank->context.wake_en); > + > if (bank->funcs.idle_enable_level_quirk) > bank->funcs.idle_enable_level_quirk(bank); > > @@ -1553,6 +1563,10 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) > bank->get_context_loss_count(dev); > > omap_gpio_dbck_disable(bank); > + > + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, > + bank->context.leveldetect0, bank->context.leveldetect1, > + bank->context.wake_en); > } > > static void omap_gpio_init_context(struct gpio_bank *p); > @@ -1563,6 +1577,10 @@ static void omap_gpio_unidle(struct gpio_bank *bank) > u32 l = 0, gen, gen0, gen1; > int c; > > + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, > + bank->context.leveldetect0, bank->context.leveldetect1, > + bank->context.wake_en); > + > /* > * On the first resume during the probe, the context has not > * been initialised and so initialise it now. Also initialise > @@ -1648,6 +1666,10 @@ static void omap_gpio_unidle(struct gpio_bank *bank) > } > > bank->workaround_enabled = false; > + > + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, > + bank->context.leveldetect0, bank->context.leveldetect1, > + bank->context.wake_en); > } > > static void omap_gpio_init_context(struct gpio_bank *p) > @@ -1720,6 +1742,7 @@ static int __maybe_unused omap_gpio_runtime_suspend(struct device *dev) > error = -EBUSY; > goto unlock; > } > + dev_dbg(dev, "%s()\n", __func__); > omap_gpio_idle(bank, true); > bank->is_suspended = true; > unlock: > @@ -1741,6 +1764,7 @@ static int __maybe_unused omap_gpio_runtime_resume(struct device *dev) > error = -EBUSY; > goto unlock; > } > + dev_dbg(dev, "%s()\n", __func__); > omap_gpio_unidle(bank); > bank->is_suspended = false; > unlock: > @@ -1827,8 +1851,8 @@ static const struct omap_gpio_platform_data omap4_pdata = { > .regs = &omap4_gpio_regs, > .bank_width = 32, > .dbck_flag = true, > - .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER | > - OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN, > + .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER /* | > + OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN */, > }; > > static const struct of_device_id omap_gpio_match[] = { > > > -- > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ > FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up > According to speedtest.net: 11.9Mbps down 500kbps up > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-07 18:14 ` Tony Lindgren @ 2018-12-07 19:03 ` Tony Lindgren 2018-12-07 19:27 ` Russell King - ARM Linux 0 siblings, 1 reply; 9+ messages in thread From: Tony Lindgren @ 2018-12-07 19:03 UTC (permalink / raw) To: Russell King - ARM Linux Cc: netdev, linux-omap, linux-arm-kernel, Grygorii Strashko * Tony Lindgren <tony@atomide.com> [181207 18:14]: > Hi, > > * Russell King - ARM Linux <linux@armlinux.org.uk> [181207 18:01]: > > Hi Tony, > > > > You know most of what's been going on from IRC, but here's the patch > > which gets me: > > > > 1) working interrupts for networking > > 2) solves the stuck-wakeup problem > > > > It also contains some of the debug bits I added. > > This is excellent news :) Will test today. Yes your patch seems to work great based on brief testing :) > > I think what this means is that we should strip out ec0daae685b2 > > ("gpio: omap: Add level wakeup handling for omap4 based SoCs"). > > Yes the only reason for the wakeup quirk was the stuck wakeup > state seen on omap4, it can be just dropped if this works. > Adding Grygorii to Cc too. I'll post a partial revert for commit ec0daae685b2 ("gpio: omap: Add level wakeup handling for omap4 based SoCs") shortly. Thanks, Tony ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-07 19:03 ` Tony Lindgren @ 2018-12-07 19:27 ` Russell King - ARM Linux 2018-12-07 20:55 ` Tony Lindgren 0 siblings, 1 reply; 9+ messages in thread From: Russell King - ARM Linux @ 2018-12-07 19:27 UTC (permalink / raw) To: Tony Lindgren; +Cc: netdev, linux-omap, linux-arm-kernel, Grygorii Strashko On Fri, Dec 07, 2018 at 11:03:12AM -0800, Tony Lindgren wrote: > * Tony Lindgren <tony@atomide.com> [181207 18:14]: > > Hi, > > > > * Russell King - ARM Linux <linux@armlinux.org.uk> [181207 18:01]: > > > Hi Tony, > > > > > > You know most of what's been going on from IRC, but here's the patch > > > which gets me: > > > > > > 1) working interrupts for networking > > > 2) solves the stuck-wakeup problem > > > > > > It also contains some of the debug bits I added. > > > > This is excellent news :) Will test today. > > Yes your patch seems to work great based on brief testing :) > > > > I think what this means is that we should strip out ec0daae685b2 > > > ("gpio: omap: Add level wakeup handling for omap4 based SoCs"). > > > > Yes the only reason for the wakeup quirk was the stuck wakeup > > state seen on omap4, it can be just dropped if this works. > > Adding Grygorii to Cc too. > > I'll post a partial revert for commit ec0daae685b2 ("gpio: omap: > Add level wakeup handling for omap4 based SoCs") shortly. Hi, You mentioned that edge mode didn't work as well as level mode on duovero smsc controller, I think this may help to solve the same issue but for edge IRQs - we need a mask_ack_irq function to avoid acking while the edge interrupt is masked. Let me know if that lowers the smsc ping latency while in edge mode. Thanks. diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 3d021f648c5d..b1ad6098e894 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -11,7 +11,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#define DEBUG #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -366,10 +366,14 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, trigger & IRQ_TYPE_LEVEL_LOW); omap_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit, trigger & IRQ_TYPE_LEVEL_HIGH); + /* + * We need the edge detect enabled for the idle mode detection + * to function on OMAP4430. + */ omap_gpio_rmw(base, bank->regs->risingdetect, gpio_bit, - trigger & IRQ_TYPE_EDGE_RISING); + trigger & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)); omap_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit, - trigger & IRQ_TYPE_EDGE_FALLING); + trigger & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)); bank->context.leveldetect0 = readl_relaxed(bank->base + bank->regs->leveldetect0); @@ -899,6 +903,19 @@ static void omap_gpio_mask_irq(struct irq_data *d) raw_spin_unlock_irqrestore(&bank->lock, flags); } +static void omap_gpio_mask_ack_irq(struct irq_data *d) +{ + struct gpio_bank *bank = omap_irq_data_get_bank(d); + unsigned offset = d->hwirq; + unsigned long flags; + + raw_spin_lock_irqsave(&bank->lock, flags); + omap_clear_gpio_irqstatus(bank, offset); + omap_set_gpio_irqenable(bank, offset, 0); + omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); + raw_spin_unlock_irqrestore(&bank->lock, flags); +} + static void omap_gpio_unmask_irq(struct irq_data *d) { struct gpio_bank *bank = omap_irq_data_get_bank(d); @@ -910,14 +927,16 @@ static void omap_gpio_unmask_irq(struct irq_data *d) if (trigger) omap_set_gpio_triggering(bank, offset, trigger); + omap_set_gpio_irqenable(bank, offset, 1); + /* For level-triggered GPIOs, the clearing must be done after - * the HW source is cleared, thus after the handler has run */ - if (bank->level_mask & BIT(offset)) { - omap_set_gpio_irqenable(bank, offset, 0); + * the HW source is cleared, thus after the handler has run. + * OMAP4 needs this done _after_ enabing the interrupt to clear + * the wakeup status. + */ + if (bank->level_mask & BIT(offset)) omap_clear_gpio_irqstatus(bank, offset); - } - omap_set_gpio_irqenable(bank, offset, 1); raw_spin_unlock_irqrestore(&bank->lock, flags); } @@ -1377,6 +1396,7 @@ static int omap_gpio_probe(struct platform_device *pdev) irqc->irq_startup = omap_gpio_irq_startup, irqc->irq_shutdown = omap_gpio_irq_shutdown, + irqc->irq_mask_ack = omap_gpio_mask_ack_irq, irqc->irq_ack = omap_gpio_ack_irq, irqc->irq_mask = omap_gpio_mask_irq, irqc->irq_unmask = omap_gpio_unmask_irq, @@ -1520,6 +1540,10 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) struct device *dev = bank->chip.parent; u32 l1 = 0, l2 = 0; + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); + if (bank->funcs.idle_enable_level_quirk) bank->funcs.idle_enable_level_quirk(bank); @@ -1553,6 +1577,10 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) bank->get_context_loss_count(dev); omap_gpio_dbck_disable(bank); + + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); } static void omap_gpio_init_context(struct gpio_bank *p); @@ -1563,6 +1591,10 @@ static void omap_gpio_unidle(struct gpio_bank *bank) u32 l = 0, gen, gen0, gen1; int c; + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); + /* * On the first resume during the probe, the context has not * been initialised and so initialise it now. Also initialise @@ -1648,6 +1680,10 @@ static void omap_gpio_unidle(struct gpio_bank *bank) } bank->workaround_enabled = false; + + dev_dbg(dev, "%s(): ld 0x%08x 0x%08x we 0x%08x\n", __func__, + bank->context.leveldetect0, bank->context.leveldetect1, + bank->context.wake_en); } static void omap_gpio_init_context(struct gpio_bank *p) @@ -1720,6 +1756,7 @@ static int __maybe_unused omap_gpio_runtime_suspend(struct device *dev) error = -EBUSY; goto unlock; } + dev_dbg(dev, "%s()\n", __func__); omap_gpio_idle(bank, true); bank->is_suspended = true; unlock: @@ -1741,6 +1778,7 @@ static int __maybe_unused omap_gpio_runtime_resume(struct device *dev) error = -EBUSY; goto unlock; } + dev_dbg(dev, "%s()\n", __func__); omap_gpio_unidle(bank); bank->is_suspended = false; unlock: @@ -1827,8 +1865,8 @@ static const struct omap_gpio_platform_data omap4_pdata = { .regs = &omap4_gpio_regs, .bank_width = 32, .dbck_flag = true, - .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER | - OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN, + .quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER /* | + OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN */, }; static const struct of_device_id omap_gpio_match[] = { -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up According to speedtest.net: 11.9Mbps down 500kbps up ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: OMAP4430 SDP with KS8851: very slow networking 2018-12-07 19:27 ` Russell King - ARM Linux @ 2018-12-07 20:55 ` Tony Lindgren 0 siblings, 0 replies; 9+ messages in thread From: Tony Lindgren @ 2018-12-07 20:55 UTC (permalink / raw) To: Russell King - ARM Linux Cc: netdev, linux-omap, linux-arm-kernel, Grygorii Strashko * Russell King - ARM Linux <linux@armlinux.org.uk> [181207 19:27]: > You mentioned that edge mode didn't work as well as level mode on > duovero smsc controller, I think this may help to solve the same > issue but for edge IRQs - we need a mask_ack_irq function to avoid > acking while the edge interrupt is masked. Let me know if that > lowers the smsc ping latency while in edge mode. Looks like smsc edge interrupt is still producing varying ping latencies with this. Seems like the mas_ack_irq is a nice improvment though. Regards, Tony ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-12-07 20:55 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-12-06 13:22 OMAP4430 SDP with KS8851: very slow networking Russell King - ARM Linux 2018-12-06 16:31 ` Tony Lindgren 2018-12-06 18:08 ` Russell King - ARM Linux 2018-12-06 22:14 ` Tony Lindgren 2018-12-07 18:00 ` Russell King - ARM Linux 2018-12-07 18:14 ` Tony Lindgren 2018-12-07 19:03 ` Tony Lindgren 2018-12-07 19:27 ` Russell King - ARM Linux 2018-12-07 20:55 ` Tony Lindgren
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).