From: Andrea Ippolito <hidden> Date: 2021-09-23 08:48:29
Hello,
has anyone had a chance to have a look at this report, and can help
making some progress on the investigation?
Please let me know if there are more suitable channels for this, since
most of the things I see in these mailing lists are patches and code
reviews, not really reports and discussions around ongoing issues.
Thanks a lot in advance.
Regards,
Andrea IPPOLITO
Il giorno ven 27 ago 2021 alle ore 08:57 Andrea Ippolito
[off-list ref] ha scritto:
From: Hans de Goede <hidden> Date: 2021-09-23 09:00:15
Hi Andrea,
On 9/23/21 10:47 AM, Andrea Ippolito wrote:
Hello,
has anyone had a chance to have a look at this report, and can help
making some progress on the investigation?
Please let me know if there are more suitable channels for this, since
most of the things I see in these mailing lists are patches and code
reviews, not really reports and discussions around ongoing issues.
Right, bugs are usually discussed in bugzila, you could consider
filing a bug here:
https://bugzilla.kernel.org/enter_bug.cgi?product=Drivers
But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
company wants to run Linux on an affected model and ends up paying
someone to look at this, or because someone with the necessary
skills happens to buy one and then gets annoyed enough by this to sink
enough time into the issue to figure things out.
This hw is still relatively new, so with some luck someone accidentally
fixes this while fixing another issue, which happens to have the
same root cause.
Short of one of these 2 happening I don't see this getting resolved
anytime soon. By all means, do file a bug for this, I just want to
set expectations about the (un)likelyness of this getting fixed
(or the bug getting much attention in general) beforehand.
Regards,
Hans
Thanks a lot in advance.
Regards,
Andrea IPPOLITO
Il giorno ven 27 ago 2021 alle ore 08:57 Andrea Ippolito
[off-list ref] ha scritto:
From: Andrea Ippolito <hidden> Date: 2021-09-23 09:06:44
Thanks a lot Hans for your quick reply :)
I will indeed proceed to filing a bug as you suggested and hope for the best.
Have a nice day!
Andrea IPPOLITO
Il giorno gio 23 set 2021 alle ore 11:00 Hans de Goede
[off-list ref] ha scritto:
Hi Andrea,
On 9/23/21 10:47 AM, Andrea Ippolito wrote:
quoted
Hello,
has anyone had a chance to have a look at this report, and can help
making some progress on the investigation?
Please let me know if there are more suitable channels for this, since
most of the things I see in these mailing lists are patches and code
reviews, not really reports and discussions around ongoing issues.
Right, bugs are usually discussed in bugzila, you could consider
filing a bug here:
https://bugzilla.kernel.org/enter_bug.cgi?product=Drivers
But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
company wants to run Linux on an affected model and ends up paying
someone to look at this, or because someone with the necessary
skills happens to buy one and then gets annoyed enough by this to sink
enough time into the issue to figure things out.
This hw is still relatively new, so with some luck someone accidentally
fixes this while fixing another issue, which happens to have the
same root cause.
Short of one of these 2 happening I don't see this getting resolved
anytime soon. By all means, do file a bug for this, I just want to
set expectations about the (un)likelyness of this getting fixed
(or the bug getting much attention in general) beforehand.
Regards,
Hans
quoted
Thanks a lot in advance.
Regards,
Andrea IPPOLITO
Il giorno ven 27 ago 2021 alle ore 08:57 Andrea Ippolito
[off-list ref] ha scritto:
From: Wolfram Sang <wsa@kernel.org> Date: 2022-01-06 13:14:32
Hi Hans,
bumping this old thread because there might be some progress and it
still affects quite some people.
But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
So, I am quite optimistic that Andrea's issue is the same one which
Miroslav Bendik dived into [1]. I will surely try to help with part of
the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
wonder if you could have a look and maybe share your thoughts?
Thanks and all the best,
Wolfram
[1] https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
From: Hans de Goede <hidden> Date: 2022-01-11 10:34:55
Hi Wolfram,
On 1/6/22 14:14, Wolfram Sang wrote:
Hi Hans,
bumping this old thread because there might be some progress and it
still affects quite some people.
quoted
But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
So, I am quite optimistic that Andrea's issue is the same one which
Miroslav Bendik dived into [1]. I will surely try to help with part of
the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
wonder if you could have a look and maybe share your thoughts?
Thanks and all the best,
Wolfram
[1] https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
Benjamin Tissoires really is the export on the synaptics PS/2 -> switch to
smbus mode devices, he did all the initial hw-enablement for them.
Benjamin, see the email Wolfram linked above. It seems that on AMD
laptops we have synaptics intertouch devices connected to a plain
PIIX4 compatible I2C controller.
So we need to either add support for SMBUS host-notify to the
PIIX4 smbus driver (at least for AMD parts) or we need to support
OOB IRQ signalling in the rmi4 code, assuming there is an OOB IRQ
at all.
I've also added Mario Limonciello from AMD's client group to the Cc,
Mario, we can really use some help / insight from AMD here, both with
the problem to detect the IO addresses of the AMD PIIX4 compatible
smbus controller as well as with smbus host-notify support, see:
https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
Regards,
Hans
From: Benjamin Tissoires <hidden> Date: 2022-01-11 11:13:23
On Tue, Jan 11, 2022 at 11:34 AM Hans de Goede [off-list ref] wrote:
Hi Wolfram,
On 1/6/22 14:14, Wolfram Sang wrote:
quoted
Hi Hans,
bumping this old thread because there might be some progress and it
still affects quite some people.
quoted
But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
So, I am quite optimistic that Andrea's issue is the same one which
Miroslav Bendik dived into [1]. I will surely try to help with part of
the PIIX I2C driver, but I lack the experience with the RMI4 driver. I
wonder if you could have a look and maybe share your thoughts?
Thanks and all the best,
Wolfram
[1] https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
Benjamin Tissoires really is the export on the synaptics PS/2 -> switch to
smbus mode devices, he did all the initial hw-enablement for them.
Benjamin, see the email Wolfram linked above. It seems that on AMD
laptops we have synaptics intertouch devices connected to a plain
PIIX4 compatible I2C controller.
Oh, nice (looking at the thread). IIRC last time somebody tried to
communicate with those touchpads it wasn't working at all.
So we need to either add support for SMBUS host-notify to the
PIIX4 smbus driver (at least for AMD parts) or we need to support
OOB IRQ signalling in the rmi4 code, assuming there is an OOB IRQ
at all.
If the touchpad is using SMBus, we need to have Host Notify. Google
gave me the following datasheet for PIIX4
https://www.intel.com/Assets/PDF/datasheet/290562.pdf and it seems we
would need to enable something in the section 7.3.9.
However, without the hardware it's going to be tough for me to enable :/
For regular I2C touchpads, there is an OOB IRQ we can set up, but when
the devices are presented and enabled through PS/2 first, they are
using SMBus only AFAICT.
Cheers,
Benjamin
I've also added Mario Limonciello from AMD's client group to the Cc,
Mario, we can really use some help / insight from AMD here, both with
the problem to detect the IO addresses of the AMD PIIX4 compatible
smbus controller as well as with smbus host-notify support, see:
https://lore.kernel.org/r/CAPoEpV0ZSidL6aMXvB6LN1uS-3CUHS4ggT8RwFgmkzzCiYJ-XQ@mail.gmail.com
Regards,
Hans
+ Nehal from the AMD platform drivers team
On 1/11/2022 05:13, Benjamin Tissoires wrote:
On Tue, Jan 11, 2022 at 11:34 AM Hans de Goede [off-list ref] wrote:
quoted
Hi Wolfram,
On 1/6/22 14:14, Wolfram Sang wrote:
quoted
Hi Hans,
bumping this old thread because there might be some progress and it
still affects quite some people.
quoted
But I must be honest here, I don't see much progress being made
on this until someone with a significant amount of kernel / hw-enablement
experience gets it hands on one of these models. Either because some
Benjamin Tissoires really is the export on the synaptics PS/2 -> switch to
smbus mode devices, he did all the initial hw-enablement for them.
Benjamin, see the email Wolfram linked above. It seems that on AMD
laptops we have synaptics intertouch devices connected to a plain
PIIX4 compatible I2C controller.
Oh, nice (looking at the thread). IIRC last time somebody tried to
communicate with those touchpads it wasn't working at all.
quoted
So we need to either add support for SMBUS host-notify to the
PIIX4 smbus driver (at least for AMD parts) or we need to support
OOB IRQ signalling in the rmi4 code, assuming there is an OOB IRQ
at all.
Nehal - can your team please look into the lack of I2C_FUNC_SMBUS_HOST_NOTIFY? This causes SMBus touchpads to be unable to function out of PS/2 mode.
You can find many more details in the analysis that Miroslav did on what's missing in this thread:
https://lore.kernel.org/all/5fc2c68d-a9df-402a-58b5-fdd531f86b55@gmail.com/
However, without the hardware it's going to be tough for me to enable :/
For regular I2C touchpads, there is an OOB IRQ we can set up, but when
the devices are presented and enabled through PS/2 first, they are
using SMBus only AFAICT.
Cheers,
Benjamin
Hans,
This thread has splintered but it comes down to two pieces to this puzzle:
1) Systems returning SMBUS address 0xff
The address can be potentially be returned using port I/O or it can be done using MMIO.
There is already a thread in process to add support for MMIO, but last I heard it's waiting for review comments.
https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/
Besides receiving a review and modifying for review comments that patch has to spin at least one more time to extend AMD_PCI_SMBUS_REVISION_MMIO to 0x51 or later instead of 0x59 or later.
2) SMBus host notify (support for handling interrupts from slave device).
I've looped in the lead from the platform drivers team Nehal to comment
on adding this feature.
Now something else interesting - the SMBUS controller in these laptops often is listed in the ACPI tables on IRQ7 with a _HID of SMB0001.
That is adding an ISR for SMBUS Host Notify support may also potentially mean needing to revert 2bbb5fa37475d7aa5fa62f34db1623f3da2dfdfa
And maybe if we're lucky https://bugzilla.kernel.org/show_bug.cgi?id=201817 gets fixed too.
From: Wolfram Sang <wsa@kernel.org> Date: 2022-01-12 08:33:20
Hi Mario,
thanks for joining the discussion!
1) Systems returning SMBUS address 0xff
The address can be potentially be returned using port I/O or it can be done
using MMIO.
There is already a thread in process to add support for MMIO, but last I
heard it's waiting for review comments.
https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/
This thread is under active discussion again.
Now something else interesting - the SMBUS controller in these laptops often
is listed in the ACPI tables on IRQ7 with a _HID of SMB0001.
IIRC tests done by Miroslav showed that interrupt 7 was used for
completing SMBus Block transfers and alike, but not for HostNotify. He
suspects this is wired via GPIO somehow.
Would be really cool if we can fix the bugzilla entry you mentioned as
well during all this!
Happy hacking,
Wolfram
From: Miroslav Bendík <hidden> Date: 2022-01-12 12:30:11
IIRC tests done by Miroslav showed that interrupt 7 was used for
completing SMBus Block transfers and alike, but not for HostNotify. He
suspects this is wired via GPIO somehow.
This is just speculation. It may be routed to GPIO pin, but think it's more
likely that AMD implements host notify. I have looked at windwos drivers and
there is only SMBus driver bundled with synaptics.
Lets look at https://www.intel.com/Assets/PDF/datasheet/290562.pdf (PIIX4 from
Intel). There is SMBSLVCNT register (page 152). Last bit (Slave Enable) should
enable interrupt on host notify if slave address matches content of SMBSLVC.
This register is described on page 135 (SMBUS SLAVE COMMAND). Registers are
accessible using PCI configuration registers. I have tried this code before
enabling interrupts without success:
pci_write_config_word(dev, SMBSLVC, 0x2c); // synaptics
I don't know if this PDF is relevant for AMD. Newest documentation from AMD,
which i found is:
https://www.amd.com/system/files/TechDocs/55072_AMD_Family_15h_Models_70h-7Fh_BKDG.pdf
This document describes SMBusSlaveControl on same address (0x08) and SlaveEnable
looks almost identical.
The interesting part is:
"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"
Slave device should send address 10h automatically. Enabled events can be set
using SMBusSlaveEvent register. I have enabled all (set 0xff to 0x0a / 0x0b
registers), but i don't know how to set "command field". There is no register
named "command field". Intel has SMBSLVC, but i can't find corresponding
register on AMD.
Constant activity on I2C pins can be repeated host notify request from synaptics.
Last interesting fact:
I have recorded register value (except 0x02 and 0x07) after each SMBus
transaction. This is from last 2 transactions:
0200 0004 5801 0000 0fa9 00ff ff00 a8aa
0200 0001 5802 0000 0fa9 40ff ff00 a8aa
Every call has SMBusSlaveEvent (register 0x0a) 0x00 except of last command after
which device is initialized. After this call register has value 0x40. I have
written 0xff to this register to enable all events in probe function. I don't
know why it's 0x00 until last transaction.
From: Hans de Goede <hidden> Date: 2022-01-12 12:31:32
Hi,
On 1/12/22 09:33, Wolfram Sang wrote:
Hi Mario,
thanks for joining the discussion!
quoted
1) Systems returning SMBUS address 0xff
The address can be potentially be returned using port I/O or it can be done
using MMIO.
There is already a thread in process to add support for MMIO, but last I
heard it's waiting for review comments.
https://lore.kernel.org/all/20210715221828.244536-1-Terry.Bowman@amd.com/
This thread is under active discussion again.
quoted
Now something else interesting - the SMBUS controller in these laptops often
is listed in the ACPI tables on IRQ7 with a _HID of SMB0001.
IIRC tests done by Miroslav showed that interrupt 7 was used for
completing SMBus Block transfers and alike, but not for HostNotify. He
suspects this is wired via GPIO somehow.
I expect host-notify to use IRQ7 too, but that it first needs to be
enabled by poking some registers in the SMBUS controller.
Regards,
Hans
I think "SMBUSx11 I2CCommand" may be what you're looking for.
Constant activity on I2C pins can be repeated host notify request from synaptics.
Last interesting fact:
I have recorded register value (except 0x02 and 0x07) after each SMBus
transaction. This is from last 2 transactions:
0200 0004 5801 0000 0fa9 00ff ff00 a8aa
0200 0001 5802 0000 0fa9 40ff ff00 a8aa
Every call has SMBusSlaveEvent (register 0x0a) 0x00 except of last command after
which device is initialized. After this call register has value 0x40. I have
written 0xff to this register to enable all events in probe function. I don't
know why it's 0x00 until last transaction.
From: Miroslav Bendík <hidden> Date: 2022-01-15 09:39:26
I think "SMBUSx11 I2CCommand" may be what you're looking for.
This has no effect and i know (probably) why.
In AMD documentation is address ending with 0x20 ASF, not SMBus. Some registers
have same function and this is probably reason, why communication works.
This code should write 0x2c address to I2CCommand. If this is RW, then reading
should return 0x2c, but it returns 0x00.
outb_p(0x2c, (0x11 + piix4_smba)); // I2CCommand
printk(KERN_INFO "smbus I2CCommand %02x\n", inb_p(0x11 + piix4_smba));
If this is ASF, then 0x11 is read only. 0x0e, 0x0f should have initial value
0xa8 0xaa. Here is register dump:
0000 0002 5802 0000 0f59 00ff ff00 a8aa 0000 0081 0002 0400 0000 0000 0000 0000
Now i am trying to change ASF registers instead of SMBus registers.
I have tried to enable interrupts and set listen address, but it don't work or
i can't recognize the difference between interrupts generated by transfers and
interrupts generated from slave.
outb_p(0x02, 0x15 + piix4_smba); // SlaveIntrListenEn
outb_p(0x2c << 1 | 0x01, 0x09 + piix4_smba); // ListenAdr | ListenAdrEn
Here is register dump for interrupts:
https://pastebin.com/eYnb30sL
Now i am trying to change ASF registers instead of SMBus registers.
I have tried to enable interrupts and set listen address, but it don't
work or
i can't recognize the difference between interrupts generated by
transfers and
interrupts generated from slave.
Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
From: Miroslav Bendík <hidden> Date: 2022-01-15 18:10:59
[AMD Official Use Only]
quoted
Now i am trying to change ASF registers instead of SMBus registers.
I have tried to enable interrupts and set listen address, but it don't
work or
i can't recognize the difference between interrupts generated by
transfers and
interrupts generated from slave.
Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
Without change, but this (0x08 or 0x10, both are not needed) starts generating interrupts
outb_p(0x08 << 1 | 0x01, 0x09 + piix4_smba);
outb_p(0x10 << 1 | 0x01, 0x09 + piix4_smba);
It generates interrupts with frequency 10 Hz - 0.01 Hz. I don't see correlation with trackpoint / touchpad.
From: Miroslav Bendík <hidden> Date: 2022-01-17 08:39:37
[AMD Official Use Only]
quoted
Now i am trying to change ASF registers instead of SMBus registers.
I have tried to enable interrupts and set listen address, but it don't
work or
i can't recognize the difference between interrupts generated by
transfers and
interrupts generated from slave.
Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
Little bit more informations:
Interrupts are generated only if ASFx09 ListenAdr is:
(0x08 << 1) | 0x01
(0x10 << 1) | 0x01
and touchpad is initialized with synaptics_intertouch=1
There is maybe small correlation between frequency and touch, but i am
not 100% sure.
There are no register changed in interrupt handler except of
ASFx13 DataBankSel. I can't determine if interrupt is generated from
transfer, or from external event.
ASF should be system for remote management. It should have access to
SMBus and data / command registers are identical, this means, that SMBus
should work (except block transfers).
If ASF just mirrors SMBus, then question is, why i can't access to
touchpad using SMBus? One strange thing is, that i2cdetect on standard
SMbus (0xb00), port 0 returns:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- 36 37 -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Address 0x58 is exactly 0x2c (synaptics) moved 1 bit left, but i2c-piix4
correctly moves address.
From: Hans de Goede <hidden> Date: 2022-01-17 09:08:55
Hi,
On 1/17/22 09:39, Miroslav Bendík wrote:
quoted
[AMD Official Use Only]
quoted
Now i am trying to change ASF registers instead of SMBus registers.
I have tried to enable interrupts and set listen address, but it don't
work or
i can't recognize the difference between interrupts generated by
transfers and
interrupts generated from slave.
Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
Little bit more informations:
Interrupts are generated only if ASFx09 ListenAdr is:
(0x08 << 1) | 0x01
(0x10 << 1) | 0x01
and touchpad is initialized with synaptics_intertouch=1
There is maybe small correlation between frequency and touch, but i am
not 100% sure.
I know very litlle about this, but I believe that when using
host-notify that after receiving the host-notify you are supposed to
do an I2C read from the SMBus Alert Response Address (ARA, 0x0c) to find
out the source of the notify (since multiple devices on the bus may
be notify capable). I guess that the controller may not do that itself
and that as long as you have not done it the touchpad may keep repeating
the notify.
But as said I know very little about this, so take this with a big
grain of salt :) I guess you may want to read up a bit on how this
is supposed to work at the bus level. I believe that the SMBUS spec
is public.
Regards,
Hans
There are no register changed in interrupt handler except of
ASFx13 DataBankSel. I can't determine if interrupt is generated from
transfer, or from external event.
ASF should be system for remote management. It should have access to
SMBus and data / command registers are identical, this means, that SMBus
should work (except block transfers).
If ASF just mirrors SMBus, then question is, why i can't access to
touchpad using SMBus? One strange thing is, that i2cdetect on standard
SMbus (0xb00), port 0 returns:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- 36 37 -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Address 0x58 is exactly 0x2c (synaptics) moved 1 bit left, but i2c-piix4
correctly moves address.
From: Miroslav Bendík <hidden> Date: 2022-01-23 17:25:45
Dňa 17. 1. 2022 o 10:08 Hans de Goede napísal(a):
Hi,
On 1/17/22 09:39, Miroslav Bendík wrote:
quoted
quoted
[AMD Official Use Only]
quoted
Now i am trying to change ASF registers instead of SMBus registers.
I have tried to enable interrupts and set listen address, but it don't
work or
i can't recognize the difference between interrupts generated by
transfers and
interrupts generated from slave.
Try reading the value of SFx0A ASFStatus bit 5 (it's write to clear if it's an interrupt).
Little bit more informations:
Interrupts are generated only if ASFx09 ListenAdr is:
(0x08 << 1) | 0x01
(0x10 << 1) | 0x01
and touchpad is initialized with synaptics_intertouch=1
There is maybe small correlation between frequency and touch, but i am
not 100% sure.
I know very litlle about this, but I believe that when using
host-notify that after receiving the host-notify you are supposed to
do an I2C read from the SMBus Alert Response Address (ARA, 0x0c) to find
out the source of the notify (since multiple devices on the bus may
be notify capable). I guess that the controller may not do that itself
and that as long as you have not done it the touchpad may keep repeating
the notify.
But as said I know very little about this, so take this with a big
grain of salt :) I guess you may want to read up a bit on how this
is supposed to work at the bus level. I believe that the SMBUS spec
is public.
Regards,
Hans
quoted
There are no register changed in interrupt handler except of
ASFx13 DataBankSel. I can't determine if interrupt is generated from
transfer, or from external event.
ASF should be system for remote management. It should have access to
SMBus and data / command registers are identical, this means, that SMBus
should work (except block transfers).
If ASF just mirrors SMBus, then question is, why i can't access to
touchpad using SMBus? One strange thing is, that i2cdetect on standard
SMbus (0xb00), port 0 returns:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- 36 37 -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Address 0x58 is exactly 0x2c (synaptics) moved 1 bit left, but i2c-piix4
correctly moves address.
Hello,
i have no response from 0x0c (ARA). It returns -6 (ENXIO).
Exact call is:
i2c_smbus_xfer(piix4_aux_adapter, 0x0c, 0x00, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE, &data)
I hava played with ARP (address 0x61), but alweays without response (-6).
I have tried to read event status from ASF. Exact command is 0000 0001b
and subcommand 0001 0010b from ASF reference documentation. I have
enabled automatic PEC appending. I have tried to manually calculate PEC
too. To calculate PEC i have called i2c_smbus_pec with data {0xaa/b,
0x01, 0x03, 0x12, 0x10, 0x00} and then set PEC byte register, but every
call ends wih -6 (no response from device).
ASF sensor address should be 0x55 is (from register ASFx0F SensorAdr
- 0xaa shifted 1 bit right).
Exact code:
outb_p(0x20, SMBHSTCNT); // Automatically append PEC
data.block[0] = 0x03; // size
data.block[1] = 0x12; // subcommand
data.block[2] = 0x10; // version
data.block[3] = 0x00; // reserved
status = i2c_smbus_xfer(piix4_aux_adapter, 0x55, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BLOCK_DATA, &data);
Interrupts are always generated after transactions. Following conditions
are necessary to generate interrupts spontaneously:
- SlaveIntrListenEn of ASFx15 SlaveEn bit set
- ListenAdr of ASFx09 set to 0x08 or 0x10
- ListenAdrEn of ASFx09 bit set
- psmouse loaded with synaptics_intertouch=1
Only ASFx13 DataBankSel is modified externally. Value is always 0x8?.
I have tried to check Databank?Full and if it set i am calling
i2c_handle_smbus_host_notify and cleaning bit. Sometimes it responds to
cursor move action, sometimes not. Sampling rate varies.
I don't know if this interrupt is host notify. It has some corellation,
but it may be something like bus error or event buffer full. I don't
know.
Here is video demonstration:
https://youtu.be/9pjxyiWA1a8
Before loading psmouse with synaptics_intertouch there are no
interrupts. After unloading, there are again no interrupts.
In ASF documentation is description of ASF_ALRT field of ASF!
description table, but my bios contains only ASFT record of MNVS
OperationRegion. I don't know if i should access this, or something
else.
From: Miroslav Bendík <hidden> Date: 2022-01-30 13:14:52
Hello,
i have small status update.
First most important information:
On AMD is trackpoint connected to ASF bus (similar to SMBus, but with
other control registers).
This bus has interrupt. After boot always generates interrupts for each
transaction. After playing it stops generating interrupts for
transaction, i don't know exactly why. More important is, that it can
generate interrupts when receives message from slave to broadcast
address (0x08).
To enable interrupts we should set:
ListenAddr to 0x08 and ListenAddrEn to 1:
outb_p((0x08 << 1) | 0x01, 0x09 + piix4_smba);
Then SlaveIntrListenEn of SlaveEn should be set to 1:
outb_p(inb_p(0x15 + piix4_smba) | 0x02, 0x15 + piix4_smba);
Now funny part, how to read address of slave device
(0x2c for synaptics):
Important register is ASFx13 DataBankSel register. If interrupt is
generated from slave device, then DataBankxFull is set. Address can be
retrieved using block read from 0x07 (DataIndex) register. Before
reading register SetReadHostDataBank should be 0. After setting
DataBankSel i am reading HostControl (dummy read), then reading form
DataIndex value 0x08 (broadcast address) and 0x2c (device, that wanted
attention). I am using following code, but it don't work good. Sometimes
there is bad value, sometimes it's reversed, first read gives 0x2c,
second 0x10. Don't know why. I have looked on decompiled windows driver
from synaptics and it looks, that there is special handling for
different DataBankSel values. I don't know exactly why, but problems are
rare, for now i am ignoring problems.
static u8 read_asf_data_bank(unsigned short piix4_smba, u8 bank_number)
{
outb_p(bank_number << 4, 0x13 + piix4_smba);
inb_p(0x02 + piix4_smba); // reset DataIndex
inb_p(0x07 + piix4_smba); // read SMBus broadcast address
return inb_p(0x07 + piix4_smba);
}
static irqreturn_t piix4_isr(int irq, void *dev_id)
{
//struct i2c_adapter *piix4_adapter = (struct i2c_adapter *)dev_id;
//struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
unsigned short piix4_smba = 0xb20;
u8 bank_sel;
u8 address[2] = {0x00, 0x00};
u8 *current_address;
current_address = &address[0];
bank_sel = inb_p(0x13 + piix4_smba); // DataBankSel
if ((bank_sel & 0x0c) == 0x00) { // bits DataBankxFull not set
return IRQ_HANDLED;
}
printk(KERN_INFO "Bank=%02x\n", bank_sel);
if ((bank_sel & 0x01) == 0) { // Last touched bank is 0
if (bank_sel & 0x08) {
*current_address = read_asf_data_bank(piix4_smba, 1);
current_address++;
}
if (bank_sel & 0x04) {
*current_address = read_asf_data_bank(piix4_smba, 0);
}
}
else { // Last touched bank is 1
if (bank_sel & 0x04) {
*current_address = read_asf_data_bank(piix4_smba, 0);
current_address++;
}
if (bank_sel & 0x08) {
*current_address = read_asf_data_bank(piix4_smba, 1);
}
}
outb_p(bank_sel & 0x0c, 0x13 + piix4_smba); // Clear DataBankxFull
printk(KERN_INFO "Address=%02x %02x\n", address[0] >> 1, address[1]
quoted
1);
if (address[0] != 0x00) {
i2c_handle_smbus_host_notify(piix4_aux_adapter, address[0] >> 1);
}
if (address[1] != 0x00 && address[1] != address[0]) {
i2c_handle_smbus_host_notify(piix4_aux_adapter, address[1] >> 1);
}
return IRQ_HANDLED;
}
Now, when i load module i see this in log:
i2c i2c-11: Error: no response!
rmi4_f12 rmi4-00.fn12: Failed to read object data. Code: -6.
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 323 Y: 301 Z: 79 WX: 9 WY: 2
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 271 Y: 378 Z: 73 WX: 8 WY: 4
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 468 Y: 378 Z: 72 WX: 7 WY: 3
Bank=8d
Address=2c 2c
i2c i2c-11: Bus collision! SMBus may be locked until next hard reset. (sorry!)
rmi4_f12 rmi4-00.fn12: Failed to read object data. Code: -5.
Bank=8d
Address=2c 2c
input input92: rmi_2d_sensor_abs_report: obj[0]: type: 0x01 X: 563 Y: 373 Z: 73 WX: 7 WY: 2
Bank=8d
Address=2c 2c
i2c i2c-11: Bus collision! SMBus may be locked until next hard reset. (sorry!)
rmi4_f12 rmi4-00.fn12: Failed to read object data. Code: -5.
There are too many bus collisions a no responses. This is my
implementation of piix4_access_asf
static s32 piix4_access_asf(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data)
{
struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
unsigned short piix4_smba = adapdata->smba;
int timeout = 0;
int retval;
u8 temp;
// Acquire IMC semaphore
outb_p(0x01, 0x14 + piix4_smba);
while ((++timeout < MAX_TIMEOUT) && (!((temp = inb_p(0x14 + piix4_smba)) & 0x01))) {
usleep_range(250, 500);
}
if ((temp & 0x01) == 0) {
printk(KERN_INFO "lock not acquired\n");
return -EBUSY;
}
outb_p(0x80, 0x13 + piix4_smba); // Set DataBankSel to host bank
retval = piix4_access(adap, addr, flags, read_write, command, size, data);
// Release semphore
outb_p(0x02, 0x14 + piix4_smba);
return retval;
}
Before transaction i am requesting HostSemaphore. Semaphore is correctly
acquired. Always. I don't know how exactly i should avoid bus conflicts.
Interrupts are sometimes generated with low frequency, sometimes with
high frequency. I don't know exactly why. Frequency changes after
restart of psmouse driver. Frequency changes with touch activity too, if
starts generating with high frequency and then i don't touch anything,
then frequency goes down. After touchpad activity frequency again goes
up.
Here is video with current state:
https://youtu.be/tf850B7UTWA
From: Miroslav Bendík <hidden> Date: 2022-02-06 18:13:13
Hello,
feature host notify is now implemented. Trackpoint / touchpad is working pretty stable with high sample rate. But ... i can't disable interrupts.
It can generatete 10 000 interrupts/s in extreme case with loaded pinctrl_amd when device is idle. But it works: https://youtu.be/L4oKt500kNo
SMBus is probably implemented correctly. It looks, like RMI4 is sending notifications constantly, even when interrupt bits are clean.
Attached patch is full of hacks, i warn anyone who would like to use it, i am not responsible for any hardware damage and hard-coded values like interrupt number should be changed manually.
Now more details:
Windows driver is fully interrupt driven. Therefore i tried to implement interrupt driven transaction. This was pretty easy. First implemented function was quick write.
I thought that interrupt is triggered after each transaction. After first transaction no interrupt was triggered. Each next transaction triggered interrupt 7us after starting transaction. This was impossible, because quick write contains 10 bits (start, 7 bit address, r/w and ack) transferred at 100kHz (readed from PM register AsfClkSel). Minimum time is 100us. Interrupt was generated after cleaning of interrupt bit or after disabling device. IRQ 7 has probably wrong type / polarity.
Lets look at relevant section of DSDT:
Scope (_SB.PCI0)
{
Device (SMB1)
{
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}
})
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
}
}
Interrupt 7 is level triggered and has active low state (standard value for PCI). Now lets look at /proc/interrupts
IR-IO-APIC 2-edge timer
IR-IO-APIC 1-edge i8042
IR-IO-APIC 7-edge piix4_smbus
IR-IO-APIC 8-edge rtc0
IR-IO-APIC 9-fasteoi acpi
IR-IO-APIC 10-edge AMDI0010:00
IR-IO-APIC 11-edge AMDI0010:01
IR-IO-APIC 12-edge i8042
This probably happens at signal level:
- r reset host interrupt status
- s start transaction
- e end transaction
11111111111111111111111111 111111111111111111
0 1 0
0 1 0
0 1 0
00000000 0000000
| | | | | |
r-1 s-1 e-1 r-2 s-2 e-2
Interrupt is triggered on rising edge (r-2). I have tried to set type / polarity using devm_request_irq / irq_set_irq_type, but this has no effect. Temporary i have written hack to arch/x86/kernel/apic/io_apic.c:
if (mp_irq_entries == 7) {
m->irqflag = MP_IRQPOL_ACTIVE_LOW | MP_IRQTRIG_LEVEL;
}
Now interrupt are triggered at right time with correct polarity.
PCI uses level triggered interrupts. Interrupt flags must be cleared. When there is not cleared interrupt flag, then interrupt will be triggered again and again. ASF has two interrupt flags: HostStatus.Intr and AsfStatus.SlaveIntr.
There is no problem with HostStatus.Intr. On slave event AsfStatus contains value 0x40 (6th bit set) instead of 0x20 (from documentation). Writing to 0x40 clears pending interrupt, 0x20 not. Disassembled windows driver writes to 0x40. AMD should fix this register in documentation.
Now i can load psmouse synaptics_intertouch=1 and device works great. Moving cursor causes bus collisions and device permanently sends host notify messages (cca 300 events / s), but it's stable.
After unloading psmouse or waiting few minutes device stops sending interrupts. After touching device interrupts are generated again. When i am not touching touchpad, interrupt status register contains zero, but host notifications are generated long time after last touch and with very high frequency. Interrupts are generated even when i don't call i2c_handle_smbus_host_notify. It can't be cause of infinite loop.
Now i don't know why RMI4 sends constantly notifications. I don't have current documentation (my documentation don't contains any new function like F03). Maybe there is new method to clear interrupts..