mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 15:27:29 +00:00
intel_th: Perform time resync on capture start
On some devices (TH 2.x devices at the moment), the internal time counter is initially not synchronized to the global crystal clock, so the time stamps it produces will not be useful. In this case, the driver needs to force the time counter resync. This applies the workaround to relevant devices. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
This commit is contained in:
parent
29e15e83a9
commit
a0e7df335a
5 changed files with 82 additions and 9 deletions
|
@ -27,6 +27,49 @@
|
|||
|
||||
#define BAR_MASK (BIT(TH_MMIO_CONFIG) | BIT(TH_MMIO_SW))
|
||||
|
||||
#define PCI_REG_NPKDSC 0x80
|
||||
#define NPKDSC_TSACT BIT(5)
|
||||
|
||||
static int intel_th_pci_activate(struct intel_th *th)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(th->dev);
|
||||
u32 npkdsc;
|
||||
int err;
|
||||
|
||||
if (!INTEL_TH_CAP(th, tscu_enable))
|
||||
return 0;
|
||||
|
||||
err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
|
||||
if (!err) {
|
||||
npkdsc |= NPKDSC_TSACT;
|
||||
err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
|
||||
}
|
||||
|
||||
if (err)
|
||||
dev_err(&pdev->dev, "failed to read NPKDSC register\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void intel_th_pci_deactivate(struct intel_th *th)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(th->dev);
|
||||
u32 npkdsc;
|
||||
int err;
|
||||
|
||||
if (!INTEL_TH_CAP(th, tscu_enable))
|
||||
return;
|
||||
|
||||
err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
|
||||
if (!err) {
|
||||
npkdsc |= NPKDSC_TSACT;
|
||||
err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
|
||||
}
|
||||
|
||||
if (err)
|
||||
dev_err(&pdev->dev, "failed to read NPKDSC register\n");
|
||||
}
|
||||
|
||||
static int intel_th_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
|
@ -47,6 +90,9 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
|
|||
if (IS_ERR(th))
|
||||
return PTR_ERR(th);
|
||||
|
||||
th->activate = intel_th_pci_activate;
|
||||
th->deactivate = intel_th_pci_deactivate;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return 0;
|
||||
|
@ -59,6 +105,10 @@ static void intel_th_pci_remove(struct pci_dev *pdev)
|
|||
intel_th_free(th);
|
||||
}
|
||||
|
||||
static const struct intel_th_drvdata intel_th_2x = {
|
||||
.tscu_enable = 1,
|
||||
};
|
||||
|
||||
static const struct pci_device_id intel_th_pci_id_table[] = {
|
||||
{
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),
|
||||
|
@ -96,17 +146,17 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
|
|||
{
|
||||
/* Gemini Lake */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
|
||||
.driver_data = (kernel_ulong_t)0,
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{
|
||||
/* Cannon Lake H */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
|
||||
.driver_data = (kernel_ulong_t)0,
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{
|
||||
/* Cannon Lake LP */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
|
||||
.driver_data = (kernel_ulong_t)0,
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue