Commit 36974daf authored by David E. Box's avatar David E. Box Committed by Hans de Goede

platform/x86: intel_pmc_core: Ignore GBE LTR on Tiger Lake platforms

Due to a HW limitation, the Latency Tolerance Reporting (LTR) value
programmed in the Tiger Lake GBE controller is not large enough to allow
the platform to enter Package C10, which in turn prevents the platform from
achieving its low power target during suspend-to-idle.  Ignore the GBE LTR
value on Tiger Lake. LTR ignore functionality is currently performed solely
by a debugfs write call. Split out the LTR code into its own function that
can be called by both the debugfs writer and by this work around.
Signed-off-by: default avatarDavid E. Box <david.e.box@linux.intel.com>
Reviewed-by: default avatarSasha Neftin <sasha.neftin@intel.com>
Cc: intel-wired-lan@lists.osuosl.org
Reviewed-by: default avatarRajneesh Bhardwaj <irenic.rajneesh@gmail.com>
Link: https://lore.kernel.org/r/20210319201844.3305399-2-david.e.box@linux.intel.comSigned-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent a01be40c
...@@ -863,34 +863,45 @@ static int pmc_core_pll_show(struct seq_file *s, void *unused) ...@@ -863,34 +863,45 @@ static int pmc_core_pll_show(struct seq_file *s, void *unused)
} }
DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
static ssize_t pmc_core_ltr_ignore_write(struct file *file, static int pmc_core_send_ltr_ignore(u32 value)
const char __user *userbuf,
size_t count, loff_t *ppos)
{ {
struct pmc_dev *pmcdev = &pmc; struct pmc_dev *pmcdev = &pmc;
const struct pmc_reg_map *map = pmcdev->map; const struct pmc_reg_map *map = pmcdev->map;
u32 val, buf_size, fd; u32 reg;
int err; int err = 0;
buf_size = count < 64 ? count : 64;
err = kstrtou32_from_user(userbuf, buf_size, 10, &val);
if (err)
return err;
mutex_lock(&pmcdev->lock); mutex_lock(&pmcdev->lock);
if (val > map->ltr_ignore_max) { if (value > map->ltr_ignore_max) {
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto out_unlock;
} }
fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset); reg = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
fd |= (1U << val); reg |= BIT(value);
pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd); pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, reg);
out_unlock: out_unlock:
mutex_unlock(&pmcdev->lock); mutex_unlock(&pmcdev->lock);
return err;
}
static ssize_t pmc_core_ltr_ignore_write(struct file *file,
const char __user *userbuf,
size_t count, loff_t *ppos)
{
u32 buf_size, value;
int err;
buf_size = min_t(u32, count, 64);
err = kstrtou32_from_user(userbuf, buf_size, 10, &value);
if (err)
return err;
err = pmc_core_send_ltr_ignore(value);
return err == 0 ? count : err; return err == 0 ? count : err;
} }
...@@ -1244,6 +1255,15 @@ static int pmc_core_probe(struct platform_device *pdev) ...@@ -1244,6 +1255,15 @@ static int pmc_core_probe(struct platform_device *pdev)
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
dmi_check_system(pmc_core_dmi_table); dmi_check_system(pmc_core_dmi_table);
/*
* On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when
* a cable is attached. Tell the PMC to ignore it.
*/
if (pmcdev->map == &tgl_reg_map) {
dev_dbg(&pdev->dev, "ignoring GBE LTR\n");
pmc_core_send_ltr_ignore(3);
}
pmc_core_dbgfs_register(pmcdev); pmc_core_dbgfs_register(pmcdev);
device_initialized = true; device_initialized = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment