Ok, here's a good news. I believe I have a code change to overcome chip bug.
A bit of debug description:
I collected couple of more win7 IOMMU traces. It turns out even win7 sometimes does not detect mask in first place. It did about 20 read/writes before reading mask again.
I mirrored those r/w in hda driver, which enabled the mask for me, and selectively removed unneeded I/Os by trial and error.
The code is in azx_reset function. In my inference, it simply resets the chip, but the exact timing between resetting the chip, polling reset bit and setting reset bit is important. I tried playing with the delays, but found only this combo to be working.
Added code it pretty crude, but I'd like to see a revised version of it in ubuntu as well as upstream driver. Here is the code added:
do{
mytemp = azx_readl(chip, GCTL); /* mytemp delacred as int, just a temperory to hold reads */
snd_printk(KERN_ERR SFX "GCTL read %x\n",mytemp);
}while(mytemp != 0x0);
Ok, here's a good news. I believe I have a code change to overcome chip bug.
A bit of debug description:
I collected couple of more win7 IOMMU traces. It turns out even win7 sometimes does not detect mask in first place. It did about 20 read/writes before reading mask again.
I mirrored those r/w in hda driver, which enabled the mask for me, and selectively removed unneeded I/Os by trial and error.
The code is in azx_reset function. In my inference, it simply resets the chip, but the exact timing between resetting the chip, polling reset bit and setting reset bit is important. I tried playing with the delays, but found only this combo to be working.
Added code it pretty crude, but I'd like to see a revised version of it in ubuntu as well as upstream driver. Here is the code added:
azx_writel(chip, GCTL, 0x100);
do{ KERN_ERR SFX "GCTL read %x\n",mytemp);
mytemp = azx_readl(chip, GCTL); /* mytemp delacred as int, just a temperory to hold reads */
snd_printk(
}while(mytemp != 0x0);
azx_writel(chip, GCTL, 0x1);
usleep_range(1000, 1200);
mytemp = azx_readw(chip, STATESTS);