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: David E. Box <david.e.box@linux.intel.com> Reviewed-by: Sasha Neftin <sasha.neftin@intel.com> Cc: intel-wired-lan@lists.osuosl.org Reviewed-by: Rajneesh Bhardwaj <irenic.rajneesh@gmail.com> Link: https://lore.kernel.org/r/20210319201844.3305399-2-david.e.box@linux.intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Родитель
a01be40c63
Коммит
36974daf53
|
@ -863,34 +863,45 @@ out_unlock:
|
|||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
|
||||
|
||||
static ssize_t pmc_core_ltr_ignore_write(struct file *file,
|
||||
const char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
static int pmc_core_send_ltr_ignore(u32 value)
|
||||
{
|
||||
struct pmc_dev *pmcdev = &pmc;
|
||||
const struct pmc_reg_map *map = pmcdev->map;
|
||||
u32 val, buf_size, fd;
|
||||
int err;
|
||||
|
||||
buf_size = count < 64 ? count : 64;
|
||||
|
||||
err = kstrtou32_from_user(userbuf, buf_size, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
u32 reg;
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&pmcdev->lock);
|
||||
|
||||
if (val > map->ltr_ignore_max) {
|
||||
if (value > map->ltr_ignore_max) {
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
|
||||
fd |= (1U << val);
|
||||
pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd);
|
||||
reg = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
|
||||
reg |= BIT(value);
|
||||
pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, reg);
|
||||
|
||||
out_unlock:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1244,6 +1255,15 @@ static int pmc_core_probe(struct platform_device *pdev)
|
|||
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
|
||||
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);
|
||||
|
||||
device_initialized = true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче