Message ID | CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | Wrong piix4_smbus address / slow trackpoint on Thinkpad P14s gen 2 (AMD) | expand |
Address detection does not work because cd6h/cd7h port io can be disabled, but it's accessible using mmio. This patch: https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ with modified AMD_PCI_SMBUS_REVISION_MMIO fixed base address detection. Problem with RMI4 touchpad / trackpoint remains, because rmi4-smbus needs host notify feature. I have tried implement this feature, without success. Interrupts on IRQ 7 (SMBus) are generated only for block data transfers, but not for trackpoint / touchpad move actions. I have looked at pinctrl_amd and it looks, that activity is signaled using GPIO. This looks promising: cat /sys/kernel/debug/pinctrl/AMDI0030:00/pingroups: group: i2c0 pin 145 (GPIO_145) pin 146 (GPIO_146) group: i2c1 pin 147 (GPIO_147) pin 148 (GPIO_148) group: i2c2 pin 113 (GPIO_113) pin 114 (GPIO_114) group: i2c3 pin 19 (GPIO_19) pin 20 (GPIO_20) After loading psmouse with forced enabled intertouch pin 19/20 started generating events.
Hi Miroslav, > On Thinkpad P14s gen 2 with AMD (model 21A00003CK, BIOS R1MET43W - 1.13) SMBus > address detection don't work and trackpoint has slow rate (30 Hz) because can't > use SMBus. Email is divided to SMBus and trackpoint section, there are issues in > both modules. Do you think this is this the same issue as described in https://bugzilla.kernel.org/show_bug.cgi?id=214597? Thank you for your detailed analysis! Wolfram
Hi again, > Address detection does not work because cd6h/cd7h port io can be > disabled, but it's accessible using mmio. This patch: > https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ > with modified AMD_PCI_SMBUS_REVISION_MMIO fixed base address > detection. Okay, this patch is stalled because Terry is waiting for review comments. I'll mention the high priority. > Problem with RMI4 touchpad / trackpoint remains, because rmi4-smbus > needs host notify feature. I have tried implement this feature, > without success. Interrupts on IRQ 7 (SMBus) are generated only for > block data transfers, but not for trackpoint / touchpad move actions. > I have looked at pinctrl_amd and it looks, that activity is signaled > using GPIO. This looks promising: Isn't the interrupt described in the ACPI tables? All the best, Wolfram
Hello, > Do you think this is this the same issue as described in > https://bugzilla.kernel.org/show_bug.cgi?id=214597 <https://bugzilla.kernel.org/show_bug.cgi?id=214597>? Probably not. > Isn't the interrupt described in the ACPI tables? Probably not. I am just web developer, i am not 100% sure, but i have not seen anything usable in ACPI tables: https://mireq.linuxos.sk/kernel/p14s_gen2_amd_acpi_tables.tar.xz Most important section with SMBus is here: https://lore.kernel.org/all/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com/ This section looked promising: Scope (_SB.I2CB) { Device (TPNL) { Name (_HID, "XXXX0000") // _HID: Hardware ID Name (_CID, "PNP0C50" /* HID Protocol Device (I2C bus) */) // _CID: Compatible ID Name (_S0W, 0x03) // _S0W: S0 Device Wake State Name (HID2, 0x00) Name (POIO, 0x00) Name (SBFB, ResourceTemplate () { I2cSerialBusV2 (0x0000, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.I2CB", 0x00, ResourceConsumer, _Y0C, Exclusive, ) }) Name (SBFG, ResourceTemplate () { GpioInt (Level, ActiveLow, ExclusiveAndWake, PullNone, 0x0000, "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { // Pin list 0x0005 } }) CreateWordField (SBFB, \_SB.I2CB.TPNL._Y0C._ADR, BADR) // _ADR: Address CreateDWordField (SBFB, \_SB.I2CB.TPNL._Y0C._SPE, SPED) // _SPE: Speed Name (ITML, Package (0x0A) { Package (0x07) { 0x04F3, 0x2A3B, 0x10, 0x01, 0x01, "ELAN901C", 0x01 }, but method _STA returned 0x0 (device not present). There is no activity on pin 5. My device has synaptics trackpoint/touchpad, not elantech. I think, that this section is for touchscreen (not on my device). More infomations to GPIO: Following command does nothing if psmouse is loaded without synaptics_intertouch: gpiomon --num-events=1000 gpiochip0 19 After loading psmouse with intertouch it catches constantly cca 2000 changes/s. There are some changes like two rising / falling edges directly behind each other. I think, that clok is much faster, than gpiomon monitoring speed, catching communication with this command would be useless. I don't know why there is constant communication from trackpoint/touchpad to GPIO 19/20. Maybe some notification mechanism, attention, maybe something which stops after clearing some bit, i dont know. Schematic from Lenovo, documentation or anything useful wold be great, but whithout this i am just guessing. Pins 19/20 should be SCL/SDA of I2C3 (from coreboot, id don't know source of pin description: https://github.com/coreboot/coreboot/blob/cf39336ccfcc363162395bddf65113900aaf19fe/src/soc/amd/cezanne/include/soc/gpio.h#L152
Hello Miroslav, forgive me if it's a dumb question, but would this also apply to Intel platforms, or this kind of stuff chip maker specific? I got an Intel Tiger Lake. Thanks! Andrea IPPOLITO Il giorno gio 6 gen 2022 alle ore 16:03 Miroslav Bendík <miroslav.bendik@gmail.com> ha scritto: > > Address detection does not work because cd6h/cd7h port io can be > disabled, but > it's accessible using mmio. This patch: > https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ > with > modified AMD_PCI_SMBUS_REVISION_MMIO fixed base address detection. > > Problem with RMI4 touchpad / trackpoint remains, because rmi4-smbus > needs host > notify feature. I have tried implement this feature, without success. > Interrupts > on IRQ 7 (SMBus) are generated only for block data transfers, but not for > trackpoint / touchpad move actions. I have looked at pinctrl_amd and it > looks, > that activity is signaled using GPIO. This looks promising: > > cat /sys/kernel/debug/pinctrl/AMDI0030:00/pingroups: > > group: i2c0 > pin 145 (GPIO_145) > pin 146 (GPIO_146) > > group: i2c1 > pin 147 (GPIO_147) > pin 148 (GPIO_148) > > group: i2c2 > pin 113 (GPIO_113) > pin 114 (GPIO_114) > > group: i2c3 > pin 19 (GPIO_19) > pin 20 (GPIO_20) > > After loading psmouse with forced enabled intertouch pin 19/20 started > generating events. >
Hello, > forgive me if it's a dumb question, but would this also apply to Intel > platforms, or this kind of stuff chip maker specific? this is specific problem with SMBus without host notify function. I don't know if new intel hardware has problem with host notify.
Summary of synaptics_intertouch problem on Thinkpad with Ryzen 5850U: Problem with wrong base address is fixed using this patch: https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ Second problem is, that RMI4 driver don't work with i2c-piix4, because it needs I2C_FUNC_SMBUS_HOST_NOTIFY. I have added I2C_FUNC_SMBUS_HOST_NOTIFY to piix4_func and psmouse can be loaded with synaptics_intertouch=1 parameter. Here is output with rmi_core debug_flags=0xfffd - https://pastebin.com/xGRHyyXV Synaptics is on address 0x2c (value 0x58/0x59 in SMBus register, bit 1 is r/w). Command i2cdetect -l can see i2c busses: i2cdetect -l i2c-3 i2c AMDGPU DM i2c hw bus 1 I2C adapter i2c-10 smbus SMBus PIIX4 adapter port 2 at 0b00 SMBus adapter i2c-1 i2c Synopsys DesignWare I2C adapter I2C adapter i2c-8 i2c AMDGPU DM aux hw bus 3 I2C adapter i2c-6 i2c AMDGPU DM aux hw bus 0 I2C adapter i2c-4 i2c AMDGPU DM i2c hw bus 2 I2C adapter i2c-11 smbus SMBus PIIX4 adapter port 1 at 0b20 SMBus adapter i2c-2 i2c AMDGPU DM i2c hw bus 0 I2C adapter i2c-0 i2c Synopsys DesignWare I2C adapter I2C adapter i2c-9 smbus SMBus PIIX4 adapter port 0 at 0b00 SMBus adapter i2c-7 i2c AMDGPU DM aux hw bus 2 I2C adapter i2c-5 i2c AMDGPU DM i2c hw bus 3 I2C adapter Device is visible on address 0x2c (output when psmouse is loaded with smbus_intertouch): i2cdetect -q -y 11 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- I can add this call i2c_handle_smbus_host_notify(piix4_aux_adapter, 0x2c); to end of piix4_transaction and i have working touchpad / trackpoint. I can move, i can click and evhz reports rate 100Hz, which is much better than 39 with PS/2 protocol. I know, this is endless loop, which generates on my machine 2000 interrupts/s and it can break some features like sleep. Current state is, that everything works with one exception - cursor moved / click interrupt. I don't know which interrupt / pin generates this event. Now what i have tried: Interrupt line can be retrieved using ACPI. More informations and links to full ACPI tables are here: https://lore.kernel.org/all/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com/ I have added this code to end of piix_probe: retval = devm_request_irq(&dev->dev, dev->irq, piix4_isr, IRQF_SHARED, "piix4_smbus", piix4_aux_adapter); if (!retval) { printk(KERN_INFO "smbus Using irq %d\n", dev->irq); } else { printk(KERN_INFO "smbus No irq %d\n", dev->irq); } PCI IRQ is set, because i have added it to PCI quirks (temporary hack). Synaptics is connected to aux adaptor, i am registering irq wit aux adapter. I have added InterruptEnable call (bit 0) in SMBUSx02 SMBusControl register (register numbers are from AMD BKDG - https://www.amd.com/en/support/tech-docs?keyword=bkdg): unsigned short piix4_smba = 0xb20; outb_p(0x01, (0x02 + piix4_smba)); Now i have tried to check SMBusStatus and SMBusSlaveStatus in interrupt handler, but they are not usable. First register is cleared directly in transfer function, which is called before interrupt handler and second is always zero. It looks, that interrupt is triggered only after data transfer, but not for host notification event from slave. I have added some print statements, to see, what happended. This code dumps registers: static void piix4_dump_registers(struct i2c_adapter *piix4_adapter, char *label) { struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); unsigned short piix4_smba = adapdata->smba; int i; u8 d[16]; for (i = 0; i < 16; ++i) { if (i == 2 || i == 7) d[i] = 0; else d[i] = inb_p(i + piix4_smba); } printk(KERN_INFO "smb registers: %s %02x%02x ...); } There are problems with reading form registers 2 and 7. It breaks communication, i don't know why. Now this is interrupt handler: static irqreturn_t piix4_isr(int irq, void *dev_id) { struct i2c_adapter *piix4_adapter = (struct i2c_adapter *)dev_id; piix4_dump_registers(piix4_adapter, "isr "); return IRQ_HANDLED; } I have added piix4_dump_register after transaction, but before clearing status. Output is on this link: https://pastebin.com/4mLBk0U7 After last line there is no output from RMI4/SMBus. Only this line has set 0x0a register (SMBusSlaveEvent) which looks like event from slave. This line is generated after transaction, but not from interrupt handler. Interrupt is not called for slave events. Now i have tried to enable interrupts from slave events. I have added this code to probe function (again, numeric addresses, but i can find numbers faster in reference documentation): outb_p(0x80, (0x02 + piix4_smba)); // Reset to SMBusControl outb_p(0x01, (0x02 + piix4_smba)); // InterruptEnable to SMBusControl outb_p(inb_p(0x01 + piix4_smba) | 0x02, (0x01 + piix4_smba)); // SlaveInit to SMBusSlaveStatus outb_p(0x2c << 1, (0x04 + piix4_smba)); // write 0x2c address ? outb_p(0xff, (0x0a + piix4_smba)); // enable all slave events onSMBusSlaveEvent outb_p(0xff, (0x0b + piix4_smba)); // enable all slave events outb_p(inb_p(0x08 + piix4_smba) | 0x01, (0x08 + piix4_smba)); // SlaveEnable outb_p(inb_p(0x08 + piix4_smba) | 0x08, (0x08 + piix4_smba)); // SMBusAlertEnable outb_p(inb_p(0x08 + piix4_smba) | 0x02, (0x08 + piix4_smba)); // SMBusShadow1EN outb_p(inb_p(0x08 + piix4_smba) | 0x04, (0x08 + piix4_smba)); // SMBusShadow2EN I have tried other combinations, but without success. This part of documentation looks like description of SMBus host notify: SMBusShadow1En. Read-write. Reset: 0. Enable the generation of an interrupt or resume event upon an external SMBus master generating a transaction with an address that matches the SMBus Shadow 1 register. SlaveEnable. Read-write. Reset: 0. Enable the generation of an interrupt or resume event upon an external SMBus master generating a transaction with an address that matches the host controller slave port of 10h, a command field that matches the SMBus slave control register, and a match of corresponding enabled events. I don't know how should i exactly interpret this part. I don't know what is SMBus slave control register. It looks like this part is copied from PIIX4 documentation from intel (https://www.intel.com/Assets/PDF/datasheet/290562.pdf), but without exact description how matching works. I have looked at other options how to retrieve interrupt, for example amd_pinctl GPIO. This looked promising: cat /sys/kernel/debug/pinctrl/AMDI0030\:00/pingroups registered pin groups: group: i2c0 pin 145 (GPIO_145) pin 146 (GPIO_146) group: i2c1 pin 147 (GPIO_147) pin 148 (GPIO_148) group: i2c2 pin 113 (GPIO_113) pin 114 (GPIO_114) group: i2c3 pin 19 (GPIO_19) pin 20 (GPIO_20) Pins 19/20 are normally idle, but after loading psmouse with intertouch, then there is constant activity (i can capture cca 2000 evnets/s using gpiomon, frequency is probably much higher). I don't know if this is usable, but looks, that this is i2c line from synaptics. I have not found interrupt pin. On this link is output of gpiomon --num-events=5000 gpiochip0 19 20: https://pastebin.com/B9XamDZA This is everything, that i know. It thin, that i have forgotten some trivial call, to unmask interrupt, but really, i don't know what. With working interrupt, enabling RMI4 over piix4-smbus should be trivial.
> Summary of synaptics_intertouch problem on Thinkpad with Ryzen 5850U: A pity the threads are a bit mixed, but some more information about previous attempts can be found in this thread: https://lore.kernel.org/r/42c83ec8-bbac-85e2-9ab5-87e59a679f95@redhat.com > Problem with wrong base address is fixed using this patch: > https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ This patch is under discussion again.
Hello, i think, that SMBus works now pretty good and last problem is screaming interrupt from synaptics (1000 irq/s). I need little help to solve this problem. Little summary first: On this thinkpad is synaptics trackpoint/touchpad connected to PIIX4. To enable RMI4 mode, SMBus driver should support host notify protocol. I have added support of host notify and replaced active waiting transaction with completer + interrupt. Driver is now pretty stable and works way better, than old implementation. For example i2c-detect shows real devices (previous transaction code showed all addresses from 0x1c as active). Patch on following link is still hack, has hardcoded IRQ and supports host notifications and interrupts only on auxiliary port. I can implement other ports later. Patch: https://lore.kernel.org/all/c9b0b147-2907-ff41-4f13-464b3b891c50@wisdomtech.sk/ This patch includes PM register access using MMIO: https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ Now i can load psmouse synaptics_intertouch=1 and everything works great, but it uses 5% CPU and interrupt is called 1000/s. I have changed interrupt from rising edge to active low (it's PCIE, PCIE has active low) and i have many times checked if all interrupt bits are cleared in interrupt request. Yes, they are always cleared. Interrupts are generated only after first touch if i have compiled only F12. If i compile F03, then interrupts are generated immediately after load of psmouse. After unload, interrupts are not generated (i2c-piix4 still loaded). On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). Using kernel thread with RT priority on isolated core i have tried to record pin values on GPIO pins. Latency is too high to record all transferred data. Some state changes are lost (approximately 1/50 bits). Not too low to read reliably all data, but good enough to see what happens at bus level. Here is recorded file: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_scl_sda.xz. Every byte is sample, first bit is SCL, second SDA. Sample rate is cca 500 000 Hz, but often drops under 100 000 (lost bit). On this screenshot is typical activity on bus: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_1.png (pulseview with imported raw file) Zoom to two packet is here: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_2.png First packet is SMBus host notify. Address 0x08 is SMBus host address and 0x58 is address of synaptics (0x2c << 1). Second packet is reading of interrupt status registers. Data 02 is length of interrupt status register (9 bits) and last 2 bytes are zero (idle, when moving cursor, then interrupt status register contains one bit set). Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png Before transaction SMBus slave state machine is disabled and after transaction enabled. If notification is received when state machine is disabled, then device writes only address and don't get response. If driver runs with always enabled slave state machine, then output will contain only notify + read interrupt status pairs and no separate addresses, but with this mode bus collisions occur more often. Here is dmesg output: https://pastebin.com/RdDYHJn0 Cursor is moved until 2862.8, then i have not touched trackpoint. Idle device don't produce bus collisions. Moving cursor produces collisions, but sample rate is stable 100Hz, which is way better, than <40 Hz with PS/2 mode. I don't know how to solve collisions. Maybe they are related to not silenced host notifications. If i were to be optimistic, then i would say that clearing interrupt vector will solve all problems. According old RMI4 documentation, reading from interrupt status register should clear interrupts (status register is cleared), but this don't prevent device form sending host notifications. Maybe exists new way to disable interrupts. I don't know, i have no access to current documentation. My device has this signature: Synaptics, product: TM3471-030, fw id: 3418235 Any help welcome.
On 2/12/2022 11:42, Miroslav Bendík wrote: > Hello, > i think, that SMBus works now pretty good and last problem is screaming > interrupt from synaptics (1000 irq/s). I need little help to solve this > problem. > > Little summary first: > > On this thinkpad is synaptics trackpoint/touchpad connected to PIIX4. To > enable RMI4 mode, SMBus driver should support host notify protocol. I > have added support of host notify and replaced active waiting > transaction with completer + interrupt. Driver is now pretty stable and > works way better, than old implementation. For example i2c-detect shows > real devices (previous transaction code showed all addresses from 0x1c > as active). Patch on following link is still hack, has hardcoded IRQ and > supports host notifications and interrupts only on auxiliary port. I can > implement other ports later. > > Patch: https://lore.kernel.org/all/c9b0b147-2907- > ff41-4f13-464b3b891c50@wisdomtech.sk/ > This patch includes PM register access using MMIO: https:// > lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ > > Now i can load psmouse synaptics_intertouch=1 and everything works > great, but it uses 5% CPU and interrupt is called 1000/s. I have changed > interrupt from rising edge to active low (it's PCIE, PCIE has active > low) and i have many times checked if all interrupt bits are cleared in > interrupt request. Yes, they are always cleared. Interrupts are > generated only after first touch if i have compiled only F12. If i > compile F03, then interrupts are generated immediately after load of > psmouse. After unload, interrupts are not generated (i2c-piix4 still > loaded). > > On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). Using > kernel thread with RT priority on isolated core i have tried to record > pin values on GPIO pins. Latency is too high to record all transferred > data. Some state changes are lost (approximately 1/50 bits). Not too low > to read reliably all data, but good enough to see what happens at bus > level. Here is recorded file: https://mireq.linuxos.sk/kernel/ > thinkpad_p14s/i2c_scl_sda.xz. > > Every byte is sample, first bit is SCL, second SDA. Sample rate is cca > 500 000 Hz, but often drops under 100 000 (lost bit). > > On this screenshot is typical activity on bus: https://mireq.linuxos.sk/ > kernel/thinkpad_p14s/i2c_1.png (pulseview with imported raw file) > > Zoom to two packet is here: https://mireq.linuxos.sk/kernel/ > thinkpad_p14s/i2c_2.png > > First packet is SMBus host notify. Address 0x08 is SMBus host address > and 0x58 is address of synaptics (0x2c << 1). Second packet is reading > of interrupt status registers. Data 02 is length of interrupt status > register (9 bits) and last 2 bytes are zero (idle, when moving cursor, > then interrupt status register contains one bit set). > > Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png > > Before transaction SMBus slave state machine is disabled and after > transaction enabled. If notification is received when state machine is > disabled, then device writes only address and don't get response. If > driver runs with always enabled slave state machine, then output will > contain only notify + read interrupt status pairs and no separate > addresses, but with this mode bus collisions occur more often. > > Here is dmesg output: https://pastebin.com/RdDYHJn0 > > Cursor is moved until 2862.8, then i have not touched trackpoint. > > Idle device don't produce bus collisions. Moving cursor produces > collisions, but sample rate is stable 100Hz, which is way better, than > <40 Hz with PS/2 mode. I don't know how to solve collisions. Maybe they > are related to not silenced host notifications. > > If i were to be optimistic, then i would say that clearing interrupt > vector will solve all problems. According old RMI4 documentation, > reading from interrupt status register should clear interrupts (status > register is cleared), but this don't prevent device form sending host > notifications. Maybe exists new way to disable interrupts. I don't know, > i have no access to current documentation. > > My device has this signature: > Synaptics, product: TM3471-030, fw id: 3418235 > > Any help welcome. > Sorry to bump such an old thread, but AFAIK you never came up with a good solution here. I did want to point out that there was a very recent submission by Shyam (CC'ed) [1] that adds an ASF driver (which is an extension to PIIX4). By default it's going to bind to an ACPI ID that isn't present on your system (present on newer systems only) but the hardware for ASF /should/ be present even on yours. So I was going to suggest if you still are interested in this to play with that series and come up with a way to force using ASF (perhaps by a DMI match for your system) and see how that goes. [1] https://lore.kernel.org/all/20240923080401.2167310-1-Shyam-sundar.S-k@amd.com/
On 10. 10. 2024 18:25, Mario Limonciello wrote: > On 2/12/2022 11:42, Miroslav Bendík wrote: >> Hello, >> i think, that SMBus works now pretty good and last problem is >> screaming interrupt from synaptics (1000 irq/s). I need little help >> to solve this problem. >> >> Little summary first: >> >> On this thinkpad is synaptics trackpoint/touchpad connected to PIIX4. >> To enable RMI4 mode, SMBus driver should support host notify >> protocol. I have added support of host notify and replaced active >> waiting transaction with completer + interrupt. Driver is now pretty >> stable and works way better, than old implementation. For example >> i2c-detect shows real devices (previous transaction code showed all >> addresses from 0x1c as active). Patch on following link is still >> hack, has hardcoded IRQ and supports host notifications and >> interrupts only on auxiliary port. I can implement other ports later. >> >> Patch: https://lore.kernel.org/all/c9b0b147-2907- >> ff41-4f13-464b3b891c50@wisdomtech.sk/ >> This patch includes PM register access using MMIO: https:// >> lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ >> >> Now i can load psmouse synaptics_intertouch=1 and everything works >> great, but it uses 5% CPU and interrupt is called 1000/s. I have >> changed interrupt from rising edge to active low (it's PCIE, PCIE has >> active low) and i have many times checked if all interrupt bits are >> cleared in interrupt request. Yes, they are always cleared. >> Interrupts are generated only after first touch if i have compiled >> only F12. If i compile F03, then interrupts are generated immediately >> after load of psmouse. After unload, interrupts are not generated >> (i2c-piix4 still loaded). >> >> On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). Using >> kernel thread with RT priority on isolated core i have tried to >> record pin values on GPIO pins. Latency is too high to record all >> transferred data. Some state changes are lost (approximately 1/50 >> bits). Not too low to read reliably all data, but good enough to see >> what happens at bus level. Here is recorded file: >> https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_scl_sda.xz. >> >> Every byte is sample, first bit is SCL, second SDA. Sample rate is >> cca 500 000 Hz, but often drops under 100 000 (lost bit). >> >> On this screenshot is typical activity on bus: >> https://mireq.linuxos.sk/ kernel/thinkpad_p14s/i2c_1.png (pulseview >> with imported raw file) >> >> Zoom to two packet is here: https://mireq.linuxos.sk/kernel/ >> thinkpad_p14s/i2c_2.png >> >> First packet is SMBus host notify. Address 0x08 is SMBus host address >> and 0x58 is address of synaptics (0x2c << 1). Second packet is >> reading of interrupt status registers. Data 02 is length of interrupt >> status register (9 bits) and last 2 bytes are zero (idle, when moving >> cursor, then interrupt status register contains one bit set). >> >> Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png >> >> Before transaction SMBus slave state machine is disabled and after >> transaction enabled. If notification is received when state machine >> is disabled, then device writes only address and don't get response. >> If driver runs with always enabled slave state machine, then output >> will contain only notify + read interrupt status pairs and no >> separate addresses, but with this mode bus collisions occur more often. >> >> Here is dmesg output: https://pastebin.com/RdDYHJn0 >> >> Cursor is moved until 2862.8, then i have not touched trackpoint. >> >> Idle device don't produce bus collisions. Moving cursor produces >> collisions, but sample rate is stable 100Hz, which is way better, >> than <40 Hz with PS/2 mode. I don't know how to solve collisions. >> Maybe they are related to not silenced host notifications. >> >> If i were to be optimistic, then i would say that clearing interrupt >> vector will solve all problems. According old RMI4 documentation, >> reading from interrupt status register should clear interrupts >> (status register is cleared), but this don't prevent device form >> sending host notifications. Maybe exists new way to disable >> interrupts. I don't know, i have no access to current documentation. >> >> My device has this signature: >> Synaptics, product: TM3471-030, fw id: 3418235 >> >> Any help welcome. >> > > Sorry to bump such an old thread, but AFAIK you never came up with a > good solution here. I did want to point out that there was a very > recent submission by Shyam (CC'ed) [1] that adds an ASF driver (which > is an extension to PIIX4). By default it's going to bind to an ACPI > ID that isn't present on your system (present on newer systems only) > but the hardware for ASF /should/ be present even on yours. > > So I was going to suggest if you still are interested in this to play > with that series and come up with a way to force using ASF (perhaps by > a DMI match for your system) and see how that goes. > > [1] > https://lore.kernel.org/all/20240923080401.2167310-1-Shyam-sundar.S-k@amd.com/ Hello. Thanks for the update. It looks good as a separate driver. I had intended to split this driver, replace polling with interrupts, and convert all I/O calls to MMIO, similar to how a Windows driver operates. I paused the work because I needed documentation and fixes from other companies, and I resolved my issue using a different approach: - I have not received a response from Synaptics. - I have not received a response from Lenovo. - I have fixed the original issue - https://patchwork.kernel.org/project/linux-input/patch/71d9dc66-9576-c26f-c9d9-129217f50255@gmail.com/#24848525 - Too many subsystems are affected, some of which are currently hardly fixable. The biggest issue is interrupt support, which cannot be resolved with quirks alone. My device has this DSDT ACPI entry: Name (_HID, "SMB0001") // _HID: Hardware ID Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { IO (Decode16, 0x0B20, // Range Minimum 0x0B20, // Range Maximum 0x20, // Alignment 0x20, // Length ) IRQ (Level, ActiveLow, Shared, ) {7} }) This entry defines the IRQ number, trigger, and polarity. However, the kernel ignores this entry and only uses the "Interrupt Source Override" from the MADT table. Here are some potential solutions: - Scan ACPI for interrupts and include them in overrides - Scanning might break or fix many drivers. This is a significant change that could affect numerous buggy BIOS ACPI implementations. - Change the interrupt trigger and polarity on the fly in the ASF driver - The interrupt trigger cannot be changed with irq_set_type because it lacks an ioapic_ir_chip.irq_set_type implementation - Implement a new quirk or hook to modify interrupts - This would involve extending the quirk system to allow changes to polarity/trigger before APIC initialization. - Add the missing MADT table - Lenovo ignores this requirement. Fixing this bug might break trackpoint support on ThinkPads, as the Synaptics firmware does not behave as described in the documentation. Given the high potential for system instability with minimal gain, my requested feature may not be worth pursuing. I can maybe help with testing this new ASF driver on older hardware without specific ACPI ID.
Hi, On 13-Oct-24 7:20 PM, Miroslav Bendík wrote: > On 10. 10. 2024 18:25, Mario Limonciello wrote: >> On 2/12/2022 11:42, Miroslav Bendík wrote: >>> Hello, >>> i think, that SMBus works now pretty good and last problem is screaming interrupt from synaptics (1000 irq/s). I need little help to solve this problem. >>> >>> Little summary first: >>> >>> On this thinkpad is synaptics trackpoint/touchpad connected to PIIX4. To enable RMI4 mode, SMBus driver should support host notify protocol. I have added support of host notify and replaced active waiting transaction with completer + interrupt. Driver is now pretty stable and works way better, than old implementation. For example i2c-detect shows real devices (previous transaction code showed all addresses from 0x1c as active). Patch on following link is still hack, has hardcoded IRQ and supports host notifications and interrupts only on auxiliary port. I can implement other ports later. >>> >>> Patch: https://lore.kernel.org/all/c9b0b147-2907- ff41-4f13-464b3b891c50@wisdomtech.sk/ >>> This patch includes PM register access using MMIO: https:// lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ >>> >>> Now i can load psmouse synaptics_intertouch=1 and everything works great, but it uses 5% CPU and interrupt is called 1000/s. I have changed interrupt from rising edge to active low (it's PCIE, PCIE has active low) and i have many times checked if all interrupt bits are cleared in interrupt request. Yes, they are always cleared. Interrupts are generated only after first touch if i have compiled only F12. If i compile F03, then interrupts are generated immediately after load of psmouse. After unload, interrupts are not generated (i2c-piix4 still loaded). >>> >>> On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). Using kernel thread with RT priority on isolated core i have tried to record pin values on GPIO pins. Latency is too high to record all transferred data. Some state changes are lost (approximately 1/50 bits). Not too low to read reliably all data, but good enough to see what happens at bus level. Here is recorded file: https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_scl_sda.xz. >>> >>> Every byte is sample, first bit is SCL, second SDA. Sample rate is cca 500 000 Hz, but often drops under 100 000 (lost bit). >>> >>> On this screenshot is typical activity on bus: https://mireq.linuxos.sk/ kernel/thinkpad_p14s/i2c_1.png (pulseview with imported raw file) >>> >>> Zoom to two packet is here: https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_2.png >>> >>> First packet is SMBus host notify. Address 0x08 is SMBus host address and 0x58 is address of synaptics (0x2c << 1). Second packet is reading of interrupt status registers. Data 02 is length of interrupt status register (9 bits) and last 2 bytes are zero (idle, when moving cursor, then interrupt status register contains one bit set). >>> >>> Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png >>> >>> Before transaction SMBus slave state machine is disabled and after transaction enabled. If notification is received when state machine is disabled, then device writes only address and don't get response. If driver runs with always enabled slave state machine, then output will contain only notify + read interrupt status pairs and no separate addresses, but with this mode bus collisions occur more often. >>> >>> Here is dmesg output: https://pastebin.com/RdDYHJn0 >>> >>> Cursor is moved until 2862.8, then i have not touched trackpoint. >>> >>> Idle device don't produce bus collisions. Moving cursor produces collisions, but sample rate is stable 100Hz, which is way better, than <40 Hz with PS/2 mode. I don't know how to solve collisions. Maybe they are related to not silenced host notifications. >>> >>> If i were to be optimistic, then i would say that clearing interrupt vector will solve all problems. According old RMI4 documentation, reading from interrupt status register should clear interrupts (status register is cleared), but this don't prevent device form sending host notifications. Maybe exists new way to disable interrupts. I don't know, i have no access to current documentation. >>> >>> My device has this signature: >>> Synaptics, product: TM3471-030, fw id: 3418235 >>> >>> Any help welcome. >>> >> >> Sorry to bump such an old thread, but AFAIK you never came up with a good solution here. I did want to point out that there was a very recent submission by Shyam (CC'ed) [1] that adds an ASF driver (which is an extension to PIIX4). By default it's going to bind to an ACPI ID that isn't present on your system (present on newer systems only) but the hardware for ASF /should/ be present even on yours. >> >> So I was going to suggest if you still are interested in this to play with that series and come up with a way to force using ASF (perhaps by a DMI match for your system) and see how that goes. >> >> [1] https://lore.kernel.org/all/20240923080401.2167310-1-Shyam-sundar.S-k@amd.com/ > Hello. > > Thanks for the update. It looks good as a separate driver. I had intended to split this driver, replace polling with interrupts, and convert all I/O calls to MMIO, similar to how a Windows driver operates. I paused the work because I needed documentation and fixes from other companies, and I resolved my issue using a different approach: > > - I have not received a response from Synaptics. > - I have not received a response from Lenovo. > - I have fixed the original issue - https://patchwork.kernel.org/project/linux-input/patch/71d9dc66-9576-c26f-c9d9-129217f50255@gmail.com/#24848525 > - Too many subsystems are affected, some of which are currently hardly fixable. > > The biggest issue is interrupt support, which cannot be resolved with quirks alone. > > My device has this DSDT ACPI entry: > > Name (_HID, "SMB0001") // _HID: Hardware ID > Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings > { > IO (Decode16, > 0x0B20, // Range Minimum > 0x0B20, // Range Maximum > 0x20, // Alignment > 0x20, // Length > ) > IRQ (Level, ActiveLow, Shared, ) > {7} > }) > > This entry defines the IRQ number, trigger, and polarity. However, the kernel ignores this entry and only uses the "Interrupt Source Override" from the MADT table. Note that we already have a quirk table for this because this hits more interrupts in the legacy ISA interrupt range, see: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/resource.c#n659 note that the MADT table is already alway skipped on AMD systems, but currently only for IRQs 1/12 which are the PS/2 kbd + mouse IRQs. Regards, Hans
On 10/13/2024 23:23, Hans de Goede wrote: > Hi, > > On 13-Oct-24 7:20 PM, Miroslav Bendík wrote: >> On 10. 10. 2024 18:25, Mario Limonciello wrote: >>> On 2/12/2022 11:42, Miroslav Bendík wrote: >>>> Hello, >>>> i think, that SMBus works now pretty good and last problem is screaming interrupt from synaptics (1000 irq/s). I need little help to solve this problem. >>>> >>>> Little summary first: >>>> >>>> On this thinkpad is synaptics trackpoint/touchpad connected to PIIX4. To enable RMI4 mode, SMBus driver should support host notify protocol. I have added support of host notify and replaced active waiting transaction with completer + interrupt. Driver is now pretty stable and works way better, than old implementation. For example i2c-detect shows real devices (previous transaction code showed all addresses from 0x1c as active). Patch on following link is still hack, has hardcoded IRQ and supports host notifications and interrupts only on auxiliary port. I can implement other ports later. >>>> >>>> Patch: https://lore.kernel.org/all/c9b0b147-2907- ff41-4f13-464b3b891c50@wisdomtech.sk/ >>>> This patch includes PM register access using MMIO: https:// lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ >>>> >>>> Now i can load psmouse synaptics_intertouch=1 and everything works great, but it uses 5% CPU and interrupt is called 1000/s. I have changed interrupt from rising edge to active low (it's PCIE, PCIE has active low) and i have many times checked if all interrupt bits are cleared in interrupt request. Yes, they are always cleared. Interrupts are generated only after first touch if i have compiled only F12. If i compile F03, then interrupts are generated immediately after load of psmouse. After unload, interrupts are not generated (i2c-piix4 still loaded). >>>> >>>> On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). Using kernel thread with RT priority on isolated core i have tried to record pin values on GPIO pins. Latency is too high to record all transferred data. Some state changes are lost (approximately 1/50 bits). Not too low to read reliably all data, but good enough to see what happens at bus level. Here is recorded file: https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_scl_sda.xz. >>>> >>>> Every byte is sample, first bit is SCL, second SDA. Sample rate is cca 500 000 Hz, but often drops under 100 000 (lost bit). >>>> >>>> On this screenshot is typical activity on bus: https://mireq.linuxos.sk/ kernel/thinkpad_p14s/i2c_1.png (pulseview with imported raw file) >>>> >>>> Zoom to two packet is here: https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_2.png >>>> >>>> First packet is SMBus host notify. Address 0x08 is SMBus host address and 0x58 is address of synaptics (0x2c << 1). Second packet is reading of interrupt status registers. Data 02 is length of interrupt status register (9 bits) and last 2 bytes are zero (idle, when moving cursor, then interrupt status register contains one bit set). >>>> >>>> Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png >>>> >>>> Before transaction SMBus slave state machine is disabled and after transaction enabled. If notification is received when state machine is disabled, then device writes only address and don't get response. If driver runs with always enabled slave state machine, then output will contain only notify + read interrupt status pairs and no separate addresses, but with this mode bus collisions occur more often. >>>> >>>> Here is dmesg output: https://pastebin.com/RdDYHJn0 >>>> >>>> Cursor is moved until 2862.8, then i have not touched trackpoint. >>>> >>>> Idle device don't produce bus collisions. Moving cursor produces collisions, but sample rate is stable 100Hz, which is way better, than <40 Hz with PS/2 mode. I don't know how to solve collisions. Maybe they are related to not silenced host notifications. >>>> >>>> If i were to be optimistic, then i would say that clearing interrupt vector will solve all problems. According old RMI4 documentation, reading from interrupt status register should clear interrupts (status register is cleared), but this don't prevent device form sending host notifications. Maybe exists new way to disable interrupts. I don't know, i have no access to current documentation. >>>> >>>> My device has this signature: >>>> Synaptics, product: TM3471-030, fw id: 3418235 >>>> >>>> Any help welcome. >>>> >>> >>> Sorry to bump such an old thread, but AFAIK you never came up with a good solution here. I did want to point out that there was a very recent submission by Shyam (CC'ed) [1] that adds an ASF driver (which is an extension to PIIX4). By default it's going to bind to an ACPI ID that isn't present on your system (present on newer systems only) but the hardware for ASF /should/ be present even on yours. >>> >>> So I was going to suggest if you still are interested in this to play with that series and come up with a way to force using ASF (perhaps by a DMI match for your system) and see how that goes. >>> >>> [1] https://lore.kernel.org/all/20240923080401.2167310-1-Shyam-sundar.S-k@amd.com/ >> Hello. >> >> Thanks for the update. It looks good as a separate driver. I had intended to split this driver, replace polling with interrupts, and convert all I/O calls to MMIO, similar to how a Windows driver operates. I paused the work because I needed documentation and fixes from other companies, and I resolved my issue using a different approach: >> >> - I have not received a response from Synaptics. >> - I have not received a response from Lenovo. >> - I have fixed the original issue - https://patchwork.kernel.org/project/linux-input/patch/71d9dc66-9576-c26f-c9d9-129217f50255@gmail.com/#24848525 >> - Too many subsystems are affected, some of which are currently hardly fixable. >> >> The biggest issue is interrupt support, which cannot be resolved with quirks alone. Do you mean the interrupt support from SMBus controller which happens via the piix4 driver? Note that SMBus controller do not support interrupt and the same has been documented in the datasheet: D14F0x03C [Interrupt Line] (FCH::SMBUSPCI::IntLine) 15:8 InterruptPin: Interrupt Pin. Read. Reset: Fixed,00h. ValidValues: Value Description ------------- ------------- 00h This module does not generate interrupts. FFh-01h Interrupt pin. Thanks, Shyam >> >> My device has this DSDT ACPI entry: >> >> Name (_HID, "SMB0001") // _HID: Hardware ID >> Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings >> { >> IO (Decode16, >> 0x0B20, // Range Minimum >> 0x0B20, // Range Maximum >> 0x20, // Alignment >> 0x20, // Length >> ) >> IRQ (Level, ActiveLow, Shared, ) >> {7} >> }) >> >> This entry defines the IRQ number, trigger, and polarity. However, the kernel ignores this entry and only uses the "Interrupt Source Override" from the MADT table. > > Note that we already have a quirk table for this because this hits more > interrupts in the legacy ISA interrupt range, see: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/resource.c#n659 > > note that the MADT table is already alway skipped on AMD systems, > but currently only for IRQs 1/12 which are the PS/2 kbd + mouse > IRQs. > > Regards, > > Hans > >
On 14. 10. 2024 18:01, Shyam Sundar S K wrote: > > On 10/13/2024 23:23, Hans de Goede wrote: >> Hi, >> >> On 13-Oct-24 7:20 PM, Miroslav Bendík wrote: >>> On 10. 10. 2024 18:25, Mario Limonciello wrote: >>>> On 2/12/2022 11:42, Miroslav Bendík wrote: >>>>> Hello, >>>>> i think, that SMBus works now pretty good and last problem is screaming interrupt from synaptics (1000 irq/s). I need little help to solve this problem. >>>>> >>>>> Little summary first: >>>>> >>>>> On this thinkpad is synaptics trackpoint/touchpad connected to PIIX4. To enable RMI4 mode, SMBus driver should support host notify protocol. I have added support of host notify and replaced active waiting transaction with completer + interrupt. Driver is now pretty stable and works way better, than old implementation. For example i2c-detect shows real devices (previous transaction code showed all addresses from 0x1c as active). Patch on following link is still hack, has hardcoded IRQ and supports host notifications and interrupts only on auxiliary port. I can implement other ports later. >>>>> >>>>> Patch: https://lore.kernel.org/all/c9b0b147-2907- ff41-4f13-464b3b891c50@wisdomtech.sk/ >>>>> This patch includes PM register access using MMIO: https:// lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ >>>>> >>>>> Now i can load psmouse synaptics_intertouch=1 and everything works great, but it uses 5% CPU and interrupt is called 1000/s. I have changed interrupt from rising edge to active low (it's PCIE, PCIE has active low) and i have many times checked if all interrupt bits are cleared in interrupt request. Yes, they are always cleared. Interrupts are generated only after first touch if i have compiled only F12. If i compile F03, then interrupts are generated immediately after load of psmouse. After unload, interrupts are not generated (i2c-piix4 still loaded). >>>>> >>>>> On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). Using kernel thread with RT priority on isolated core i have tried to record pin values on GPIO pins. Latency is too high to record all transferred data. Some state changes are lost (approximately 1/50 bits). Not too low to read reliably all data, but good enough to see what happens at bus level. Here is recorded file: https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_scl_sda.xz. >>>>> >>>>> Every byte is sample, first bit is SCL, second SDA. Sample rate is cca 500 000 Hz, but often drops under 100 000 (lost bit). >>>>> >>>>> On this screenshot is typical activity on bus: https://mireq.linuxos.sk/ kernel/thinkpad_p14s/i2c_1.png (pulseview with imported raw file) >>>>> >>>>> Zoom to two packet is here: https://mireq.linuxos.sk/kernel/ thinkpad_p14s/i2c_2.png >>>>> >>>>> First packet is SMBus host notify. Address 0x08 is SMBus host address and 0x58 is address of synaptics (0x2c << 1). Second packet is reading of interrupt status registers. Data 02 is length of interrupt status register (9 bits) and last 2 bytes are zero (idle, when moving cursor, then interrupt status register contains one bit set). >>>>> >>>>> Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png >>>>> >>>>> Before transaction SMBus slave state machine is disabled and after transaction enabled. If notification is received when state machine is disabled, then device writes only address and don't get response. If driver runs with always enabled slave state machine, then output will contain only notify + read interrupt status pairs and no separate addresses, but with this mode bus collisions occur more often. >>>>> >>>>> Here is dmesg output: https://pastebin.com/RdDYHJn0 >>>>> >>>>> Cursor is moved until 2862.8, then i have not touched trackpoint. >>>>> >>>>> Idle device don't produce bus collisions. Moving cursor produces collisions, but sample rate is stable 100Hz, which is way better, than <40 Hz with PS/2 mode. I don't know how to solve collisions. Maybe they are related to not silenced host notifications. >>>>> >>>>> If i were to be optimistic, then i would say that clearing interrupt vector will solve all problems. According old RMI4 documentation, reading from interrupt status register should clear interrupts (status register is cleared), but this don't prevent device form sending host notifications. Maybe exists new way to disable interrupts. I don't know, i have no access to current documentation. >>>>> >>>>> My device has this signature: >>>>> Synaptics, product: TM3471-030, fw id: 3418235 >>>>> >>>>> Any help welcome. >>>>> >>>> Sorry to bump such an old thread, but AFAIK you never came up with a good solution here. I did want to point out that there was a very recent submission by Shyam (CC'ed) [1] that adds an ASF driver (which is an extension to PIIX4). By default it's going to bind to an ACPI ID that isn't present on your system (present on newer systems only) but the hardware for ASF /should/ be present even on yours. >>>> >>>> So I was going to suggest if you still are interested in this to play with that series and come up with a way to force using ASF (perhaps by a DMI match for your system) and see how that goes. >>>> >>>> [1] https://lore.kernel.org/all/20240923080401.2167310-1-Shyam-sundar.S-k@amd.com/ >>> Hello. >>> >>> Thanks for the update. It looks good as a separate driver. I had intended to split this driver, replace polling with interrupts, and convert all I/O calls to MMIO, similar to how a Windows driver operates. I paused the work because I needed documentation and fixes from other companies, and I resolved my issue using a different approach: >>> >>> - I have not received a response from Synaptics. >>> - I have not received a response from Lenovo. >>> - I have fixed the original issue - https://patchwork.kernel.org/project/linux-input/patch/71d9dc66-9576-c26f-c9d9-129217f50255@gmail.com/#24848525 >>> - Too many subsystems are affected, some of which are currently hardly fixable. >>> >>> The biggest issue is interrupt support, which cannot be resolved with quirks alone. > Do you mean the interrupt support from SMBus controller which happens > via the piix4 driver? > > Note that SMBus controller do not support interrupt and the same has > been documented in the datasheet: > > D14F0x03C [Interrupt Line] (FCH::SMBUSPCI::IntLine) > > 15:8 InterruptPin: Interrupt Pin. Read. Reset: Fixed,00h. > > ValidValues: > > > Value Description > ------------- ------------- > 00h This module does not generate interrupts. > FFh-01h Interrupt pin. > > Thanks, > Shyam Hello, i am using ASF documentation (48751 Rev 3.03 - February 19, 2015 BKDG for AMD Family 16h Models 00h-0Fh Processors - https://www.amd.com/en/search/documentation/hub.html#q=BKDG%2048751). There is a ASFx0A ASFStatus with SlaveIntr bit. Pointing device on my machine triggers interrupt 7 and it can be cleared using ASF when i move cursor using touchpad or trackpoint. It's possible to implement and enable I2C_CLIENT_HOST_NOTIFY flag on this hardware. Another interrupt bit Intr from ASFx00 HostStatus is 1 after transfer (interrupt 7 is triggered). Transfer can be implemented without timers and active waiting on HostBusy status (there is a loop in piix4_transaction). With regards Miroslav Bendík > >>> My device has this DSDT ACPI entry: >>> >>> Name (_HID, "SMB0001") // _HID: Hardware ID >>> Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings >>> { >>> IO (Decode16, >>> 0x0B20, // Range Minimum >>> 0x0B20, // Range Maximum >>> 0x20, // Alignment >>> 0x20, // Length >>> ) >>> IRQ (Level, ActiveLow, Shared, ) >>> {7} >>> }) >>> >>> This entry defines the IRQ number, trigger, and polarity. However, the kernel ignores this entry and only uses the "Interrupt Source Override" from the MADT table. >> Note that we already have a quirk table for this because this hits more >> interrupts in the legacy ISA interrupt range, see: >> >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/resource.c#n659 >> >> note that the MADT table is already alway skipped on AMD systems, >> but currently only for IRQs 1/12 which are the PS/2 kbd + mouse >> IRQs. >> >> Regards, >> >> Hans >> >>
On 10/14/2024 22:13, Miroslav Bendík wrote: > On 14. 10. 2024 18:01, Shyam Sundar S K wrote: >> >> On 10/13/2024 23:23, Hans de Goede wrote: >>> Hi, >>> >>> On 13-Oct-24 7:20 PM, Miroslav Bendík wrote: >>>> On 10. 10. 2024 18:25, Mario Limonciello wrote: >>>>> On 2/12/2022 11:42, Miroslav Bendík wrote: >>>>>> Hello, >>>>>> i think, that SMBus works now pretty good and last problem is >>>>>> screaming interrupt from synaptics (1000 irq/s). I need little >>>>>> help to solve this problem. >>>>>> >>>>>> Little summary first: >>>>>> >>>>>> On this thinkpad is synaptics trackpoint/touchpad connected to >>>>>> PIIX4. To enable RMI4 mode, SMBus driver should support host >>>>>> notify protocol. I have added support of host notify and >>>>>> replaced active waiting transaction with completer + interrupt. >>>>>> Driver is now pretty stable and works way better, than old >>>>>> implementation. For example i2c-detect shows real devices >>>>>> (previous transaction code showed all addresses from 0x1c as >>>>>> active). Patch on following link is still hack, has hardcoded >>>>>> IRQ and supports host notifications and interrupts only on >>>>>> auxiliary port. I can implement other ports later. >>>>>> >>>>>> Patch: https://lore.kernel.org/all/c9b0b147-2907- >>>>>> ff41-4f13-464b3b891c50@wisdomtech.sk/ >>>>>> This patch includes PM register access using MMIO: https:// >>>>>> lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/ >>>>>> >>>>>> Now i can load psmouse synaptics_intertouch=1 and everything >>>>>> works great, but it uses 5% CPU and interrupt is called 1000/s. >>>>>> I have changed interrupt from rising edge to active low (it's >>>>>> PCIE, PCIE has active low) and i have many times checked if all >>>>>> interrupt bits are cleared in interrupt request. Yes, they are >>>>>> always cleared. Interrupts are generated only after first touch >>>>>> if i have compiled only F12. If i compile F03, then interrupts >>>>>> are generated immediately after load of psmouse. After unload, >>>>>> interrupts are not generated (i2c-piix4 still loaded). >>>>>> >>>>>> On this machine I2C is accessible using GPIO 19(SCL), 20(SDA). >>>>>> Using kernel thread with RT priority on isolated core i have >>>>>> tried to record pin values on GPIO pins. Latency is too high to >>>>>> record all transferred data. Some state changes are lost >>>>>> (approximately 1/50 bits). Not too low to read reliably all >>>>>> data, but good enough to see what happens at bus level. Here is >>>>>> recorded file: https://mireq.linuxos.sk/kernel/ >>>>>> thinkpad_p14s/i2c_scl_sda.xz. >>>>>> >>>>>> Every byte is sample, first bit is SCL, second SDA. Sample rate >>>>>> is cca 500 000 Hz, but often drops under 100 000 (lost bit). >>>>>> >>>>>> On this screenshot is typical activity on bus: >>>>>> https://mireq.linuxos.sk/ kernel/thinkpad_p14s/i2c_1.png >>>>>> (pulseview with imported raw file) >>>>>> >>>>>> Zoom to two packet is here: https://mireq.linuxos.sk/kernel/ >>>>>> thinkpad_p14s/i2c_2.png >>>>>> >>>>>> First packet is SMBus host notify. Address 0x08 is SMBus host >>>>>> address and 0x58 is address of synaptics (0x2c << 1). Second >>>>>> packet is reading of interrupt status registers. Data 02 is >>>>>> length of interrupt status register (9 bits) and last 2 bytes >>>>>> are zero (idle, when moving cursor, then interrupt status >>>>>> register contains one bit set). >>>>>> >>>>>> Zoomed out: https://mireq.linuxos.sk/kernel/thinkpad_p14s/i2c_3.png >>>>>> >>>>>> Before transaction SMBus slave state machine is disabled and >>>>>> after transaction enabled. If notification is received when >>>>>> state machine is disabled, then device writes only address and >>>>>> don't get response. If driver runs with always enabled slave >>>>>> state machine, then output will contain only notify + read >>>>>> interrupt status pairs and no separate addresses, but with this >>>>>> mode bus collisions occur more often. >>>>>> >>>>>> Here is dmesg output: https://pastebin.com/RdDYHJn0 >>>>>> >>>>>> Cursor is moved until 2862.8, then i have not touched trackpoint. >>>>>> >>>>>> Idle device don't produce bus collisions. Moving cursor produces >>>>>> collisions, but sample rate is stable 100Hz, which is way >>>>>> better, than <40 Hz with PS/2 mode. I don't know how to solve >>>>>> collisions. Maybe they are related to not silenced host >>>>>> notifications. >>>>>> >>>>>> If i were to be optimistic, then i would say that clearing >>>>>> interrupt vector will solve all problems. According old RMI4 >>>>>> documentation, reading from interrupt status register should >>>>>> clear interrupts (status register is cleared), but this don't >>>>>> prevent device form sending host notifications. Maybe exists new >>>>>> way to disable interrupts. I don't know, i have no access to >>>>>> current documentation. >>>>>> >>>>>> My device has this signature: >>>>>> Synaptics, product: TM3471-030, fw id: 3418235 >>>>>> >>>>>> Any help welcome. >>>>>> >>>>> Sorry to bump such an old thread, but AFAIK you never came up >>>>> with a good solution here. I did want to point out that there >>>>> was a very recent submission by Shyam (CC'ed) [1] that adds an >>>>> ASF driver (which is an extension to PIIX4). By default it's >>>>> going to bind to an ACPI ID that isn't present on your system >>>>> (present on newer systems only) but the hardware for ASF /should/ >>>>> be present even on yours. >>>>> >>>>> So I was going to suggest if you still are interested in this to >>>>> play with that series and come up with a way to force using ASF >>>>> (perhaps by a DMI match for your system) and see how that goes. >>>>> >>>>> [1] >>>>> https://lore.kernel.org/all/20240923080401.2167310-1-Shyam-sundar.S-k@amd.com/ >>>> Hello. >>>> >>>> Thanks for the update. It looks good as a separate driver. I had >>>> intended to split this driver, replace polling with interrupts, >>>> and convert all I/O calls to MMIO, similar to how a Windows driver >>>> operates. I paused the work because I needed documentation and >>>> fixes from other companies, and I resolved my issue using a >>>> different approach: >>>> >>>> - I have not received a response from Synaptics. >>>> - I have not received a response from Lenovo. >>>> - I have fixed the original issue - >>>> https://patchwork.kernel.org/project/linux-input/patch/71d9dc66-9576-c26f-c9d9-129217f50255@gmail.com/#24848525 >>>> - Too many subsystems are affected, some of which are currently >>>> hardly fixable. >>>> >>>> The biggest issue is interrupt support, which cannot be resolved >>>> with quirks alone. >> Do you mean the interrupt support from SMBus controller which happens >> via the piix4 driver? >> >> Note that SMBus controller do not support interrupt and the same has >> been documented in the datasheet: >> >> D14F0x03C [Interrupt Line] (FCH::SMBUSPCI::IntLine) >> >> 15:8 InterruptPin: Interrupt Pin. Read. Reset: Fixed,00h. >> >> ValidValues: >> >> >> Value Description >> ------------- ------------- >> 00h This module does not generate interrupts. >> FFh-01h Interrupt pin. >> >> Thanks, >> Shyam > > Hello, > > i am using ASF documentation (48751 Rev 3.03 - February 19, 2015 BKDG > for AMD Family 16h Models 00h-0Fh Processors - > https://www.amd.com/en/search/documentation/hub.html#q=BKDG%2048751). Hi, You are referring the right document. > > There is a ASFx0A ASFStatus with SlaveIntr bit. Pointing device on my > machine triggers interrupt 7 and it can be cleared using ASF when i > move cursor using touchpad or trackpoint. It's possible to implement > and enable I2C_CLIENT_HOST_NOTIFY flag on this hardware. if you want I2C_CLIENT_HOST_NOTIFY flag, then that has to come via a software_node property and I don't think we have near future thoughts about having this in BIOS. > > Another interrupt bit Intr from ASFx00 HostStatus is 1 after transfer > (interrupt 7 is triggered). Transfer can be implemented without timers > and active waiting on HostBusy status (there is a loop in > piix4_transaction). Yeah, but this is what is being documented in the ASF databook and we have to look at the SMBHSTSTS, based on that the further ASF packets are processed. Thanks, Shyam > > With regards > Miroslav Bendík > >> >>>> My device has this DSDT ACPI entry: >>>> >>>> Name (_HID, "SMB0001") // _HID: Hardware ID >>>> Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings >>>> { >>>> IO (Decode16, >>>> 0x0B20, // Range Minimum >>>> 0x0B20, // Range Maximum >>>> 0x20, // Alignment >>>> 0x20, // Length >>>> ) >>>> IRQ (Level, ActiveLow, Shared, ) >>>> {7} >>>> }) >>>> >>>> This entry defines the IRQ number, trigger, and polarity. However, >>>> the kernel ignores this entry and only uses the "Interrupt Source >>>> Override" from the MADT table. >>> Note that we already have a quirk table for this because this hits >>> more >>> interrupts in the legacy ISA interrupt range, see: >>> >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/resource.c#n659 >>> >>> note that the MADT table is already alway skipped on AMD systems, >>> but currently only for IRQs 1/12 which are the PS/2 kbd + mouse >>> IRQs. >>> >>> Regards, >>> >>> Hans >>> >>>
diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c index a472489cc..6205f8d65 100644 --- a/drivers/input/mouse/psmouse-smbus.c +++ b/drivers/input/mouse/psmouse-smbus.c @@ -30,8 +30,8 @@ static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter) { struct psmouse_smbus_dev *smbdev; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY)) - return; + //if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY)) + // return; mutex_lock(&psmouse_smbus_mutex); @@ -196,8 +196,8 @@ static int psmouse_smbus_create_companion(struct device *dev, void *data) if (!adapter) return 0; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY)) - return 0; + //if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY)) + // return 0; client = i2c_new_scanned_device(adapter, &smbdev->board, addr_list, NULL); diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ffad14280..2f476dce7 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1765,7 +1765,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse, }; const struct i2c_board_info intertouch_board = { I2C_BOARD_INFO("rmi4_smbus", 0x2c), - .flags = I2C_CLIENT_HOST_NOTIFY, + //.flags = I2C_CLIENT_HOST_NOTIFY, }; return psmouse_smbus_init(psmouse, &intertouch_board, diff --git a/drivers/input/rmi4/rmi_smbus.c b/drivers/input/rmi4/rmi_smbus.c index 2407ea43d..3eb7193b4 100644 --- a/drivers/input/rmi4/rmi_smbus.c +++ b/drivers/input/rmi4/rmi_smbus.c @@ -281,14 +281,17 @@ static int rmi_smb_probe(struct i2c_client *client, return -ENOMEM; } + //if (!i2c_check_functionality(client->adapter, + // I2C_FUNC_SMBUS_READ_BLOCK_DATA | + // I2C_FUNC_SMBUS_HOST_NOTIFY)) { if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_HOST_NOTIFY)) { + I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { dev_err(&client->dev, "adapter does not support required functionality\n"); return -ENODEV; } + client->irq = 7; if (client->irq <= 0) { dev_err(&client->dev, "no IRQ provided, giving up\n"); return client->irq ? client->irq : -ENODEV;