Commit 08c49dc1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'platform-drivers-x86-v5.6-1' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform driver updates from Andy Shevchenko:

 - Enable thermal policy for ASUS TUF FX705DY/FX505DY

 - Support left round button on ASUS N56VB

 - Support new Mellanox platforms of basic class VMOD0009 and VMOD0010

 - Intel Comet Lake, Tiger Lake and Elkhart Lake support in the PMC
   driver

 - Big clean-up to Intel PMC core, PMC IPC and SCU IPC drivers

 - Touchscreen support for the PiPO W11 tablet

* tag 'platform-drivers-x86-v5.6-1' of git://git.infradead.org/linux-platform-drivers-x86: (64 commits)
  platform/x86: intel_pmc_ipc: Switch to use driver->dev_groups
  platform/x86: intel_pmc_ipc: Propagate error from kstrtoul()
  platform/x86: intel_pmc_ipc: Use octal permissions in sysfs attributes
  platform/x86: intel_pmc_ipc: Get rid of unnecessary includes
  platform/x86: intel_pmc_ipc: Drop ipc_data_readb()
  platform/x86: intel_pmc_ipc: Drop intel_pmc_gcr_read() and intel_pmc_gcr_write()
  platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_raw_cmd() static
  platform/x86: intel_pmc_ipc: Make intel_pmc_ipc_simple_command() static
  platform/x86: intel_pmc_ipc: Make intel_pmc_gcr_update() static
  platform/x86: intel_scu_ipc: Reformat kernel-doc comments of exported functions
  platform/x86: intel_scu_ipc: Drop intel_scu_ipc_raw_command()
  platform/x86: intel_scu_ipc: Drop intel_scu_ipc_io[read|write][8|16]()
  platform/x86: intel_scu_ipc: Drop unused macros
  platform/x86: intel_scu_ipc: Drop unused prototype intel_scu_ipc_fw_update()
  platform/x86: intel_scu_ipc: Sleeping is fine when polling
  platform/x86: intel_scu_ipc: Drop intel_scu_ipc_i2c_cntrl()
  platform/x86: intel_scu_ipc: Remove Lincroft support
  platform/x86: intel_scu_ipc: Add constants for register offsets
  platform/x86: intel_scu_ipc: Fix interrupt support
  platform/x86: intel_scu_ipcutil: Remove default y from Kconfig
  ...
parents 9e1af756 cf85e7c7
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/asic_health
Date: June 2018
KernelVersion: 4.19
Contact: Vadim Pasternak <vadimpmellanox.com>
......@@ -19,7 +18,6 @@ Description: These files show with which CPLD versions have been burned
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/fan_dir
Date: December 2018
KernelVersion: 5.0
Contact: Vadim Pasternak <vadimpmellanox.com>
......@@ -30,7 +28,6 @@ Description: This file shows the system fans direction:
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld3_version
Date: November 2018
KernelVersion: 5.0
Contact: Vadim Pasternak <vadimpmellanox.com>
......@@ -40,7 +37,6 @@ Description: These files show with which CPLD versions have been burned
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable
Date: November 2018
KernelVersion: 5.0
Contact: Vadim Pasternak <vadimpmellanox.com>
......@@ -108,7 +104,6 @@ What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_pwr_fail
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_from_comex
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_system
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_voltmon_upgrade_fail
Date: November 2018
KernelVersion: 5.0
Contact: Vadim Pasternak <vadimpmellanox.com>
......@@ -130,6 +125,12 @@ Description: These files show with which CPLD versions have been burned
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_thermal
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_wd
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_from_asic
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_reload_bios
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_sff_wd
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_swb_wd
Date: June 2019
KernelVersion: 5.3
Contact: Vadim Pasternak <vadimpmellanox.com>
......@@ -143,9 +144,65 @@ Description: These files show the system reset cause, as following:
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_thermal
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_wd
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_from_asic
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_reload_bios
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_sff_wd
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_swb_wd
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/config1
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/config2
Date: January 2020
KernelVersion: 5.6
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: These files show system static topology identification
like system's static I2C topology, number and type of FPGA
devices within the system and so on.
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_ac_pwr_fail
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_platform
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_soc
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_sw_pwr_off
Date: January 2020
KernelVersion: 5.6
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: These files show the system reset causes, as following: reset
due to AC power failure, reset invoked from software by
assertion reset signal through CPLD. reset caused by signal
asserted by SOC through ACPI register, reset invoked from
software by assertion power off signal through CPLD.
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/pcie_asic_reset_dis
Date: January 2020
KernelVersion: 5.6
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: This file allows to retain ASIC up during PCIe root complex
reset, when attribute is set 1.
The file is read/write.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/vpd_wp
Date: January 2020
KernelVersion: 5.6
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: This file allows to overwrite system VPD hardware wrtie
protection when attribute is set 1.
The file is read/write.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/voltreg_update_status
Date: January 2020
KernelVersion: 5.6
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: This file exposes the configuration update status of burnable
voltage regulator devices. The status values are as following:
0 - OK; 1 - CRC failure; 2 = I2C failure; 3 - in progress.
The file is read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ufm_version
Date: January 2020
KernelVersion: 5.6
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: This file exposes the firmware version of burnable voltage
regulator devices.
The file is read only.
......@@ -46,3 +46,13 @@ Description:
* 0 - normal,
* 1 - overboost,
* 2 - silent
What: /sys/devices/platform/<platform>/throttle_thermal_policy
Date: Dec 2019
KernelVersion: 5.6
Contact: "Leonid Maksymchuk" <leonmaxx@gmail.com>
Description:
Throttle thermal policy mode:
* 0 - default,
* 1 - overboost,
* 2 - silent
......@@ -8573,6 +8573,12 @@ S: Maintained
F: arch/x86/include/asm/intel_telemetry.h
F: drivers/platform/x86/intel_telemetry*
INTEL UNCORE FREQUENCY CONTROL
M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/intel-uncore-frequency.c
INTEL VIRTUAL BUTTON DRIVER
M: AceLan Kao <acelan.kao@canonical.com>
L: platform-driver-x86@vger.kernel.org
......
......@@ -31,30 +31,13 @@
#if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
int intel_pmc_ipc_simple_command(int cmd, int sub);
int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
u32 *out, u32 outlen, u32 dptr, u32 sptr);
int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
u32 *out, u32 outlen);
int intel_pmc_s0ix_counter_read(u64 *data);
int intel_pmc_gcr_read(u32 offset, u32 *data);
int intel_pmc_gcr_read64(u32 offset, u64 *data);
int intel_pmc_gcr_write(u32 offset, u32 data);
int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val);
#else
static inline int intel_pmc_ipc_simple_command(int cmd, int sub)
{
return -EINVAL;
}
static inline int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen,
u32 *out, u32 outlen, u32 dptr, u32 sptr)
{
return -EINVAL;
}
static inline int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
u32 *out, u32 outlen)
{
......@@ -66,26 +49,11 @@ static inline int intel_pmc_s0ix_counter_read(u64 *data)
return -EINVAL;
}
static inline int intel_pmc_gcr_read(u32 offset, u32 *data)
{
return -EINVAL;
}
static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
{
return -EINVAL;
}
static inline int intel_pmc_gcr_write(u32 offset, u32 data)
{
return -EINVAL;
}
static inline int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
{
return -EINVAL;
}
#endif /*CONFIG_INTEL_PMC_IPC*/
#endif
......@@ -22,24 +22,12 @@
/* Read single register */
int intel_scu_ipc_ioread8(u16 addr, u8 *data);
/* Read two sequential registers */
int intel_scu_ipc_ioread16(u16 addr, u16 *data);
/* Read four sequential registers */
int intel_scu_ipc_ioread32(u16 addr, u32 *data);
/* Read a vector */
int intel_scu_ipc_readv(u16 *addr, u8 *data, int len);
/* Write single register */
int intel_scu_ipc_iowrite8(u16 addr, u8 data);
/* Write two sequential registers */
int intel_scu_ipc_iowrite16(u16 addr, u16 data);
/* Write four sequential registers */
int intel_scu_ipc_iowrite32(u16 addr, u32 data);
/* Write a vector */
int intel_scu_ipc_writev(u16 *addr, u8 *data, int len);
......@@ -50,14 +38,6 @@ int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask);
int intel_scu_ipc_simple_command(int cmd, int sub);
int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
u32 *out, int outlen);
int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
u32 *out, int outlen, u32 dptr, u32 sptr);
/* I2C control api */
int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data);
/* Update FW version */
int intel_scu_ipc_fw_update(u8 *buffer, u32 length);
extern struct blocking_notifier_head intel_scu_notifier;
......
......@@ -40,13 +40,10 @@ struct telemetry_evtmap {
struct telemetry_unit_config {
struct telemetry_evtmap *telem_evts;
void __iomem *regmap;
u32 ssram_base_addr;
u8 ssram_evts_used;
u8 curr_period;
u8 max_period;
u8 min_period;
u32 ssram_size;
};
struct telemetry_plt_config {
......
......@@ -504,6 +504,20 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
item = pdata->items;
for (i = 0; i < pdata->counter; i++, item++) {
if (item->capability) {
/*
* Read group capability register to get actual number
* of interrupt capable components and set group mask
* accordingly.
*/
ret = regmap_read(priv->regmap, item->capability,
&regval);
if (ret)
goto out;
item->mask = GENMASK((regval & item->mask) - 1, 0);
}
/* Clear group presense event. */
ret = regmap_write(priv->regmap, item->reg +
MLXREG_HOTPLUG_EVENT_OFF, 0);
......
......@@ -997,7 +997,6 @@ config INTEL_SCU_IPC
config INTEL_SCU_IPC_UTIL
tristate "Intel SCU IPC utility driver"
depends on INTEL_SCU_IPC
default y
---help---
The IPC Util driver provides an interface with the SCU enabling
low level access for debug work and updating the firmware. Say
......@@ -1299,9 +1298,9 @@ config INTEL_ATOMISP2_PM
depends on PCI && IOSF_MBI && PM
help
Power-management driver for Intel's Image Signal Processor found on
Bay and Cherry Trail devices. This dummy driver's sole purpose is to
turn the ISP off (put it in D3) to save power and to allow entering
of S0ix modes.
Bay Trail and Cherry Trail devices. This dummy driver's sole purpose
is to turn the ISP off (put it in D3) to save power and to allow
entering of S0ix modes.
To compile this driver as a module, choose M here: the module
will be called intel_atomisp2_pm.
......@@ -1337,6 +1336,17 @@ config PCENGINES_APU2
To compile this driver as a module, choose M here: the module
will be called pcengines-apuv2.
config INTEL_UNCORE_FREQ_CONTROL
tristate "Intel Uncore frequency control driver"
depends on X86_64
help
This driver allows control of uncore frequency limits on
supported server platforms.
Uncore frequency controls RING/LLC (last-level cache) clocks.
To compile this driver as a module, choose M here: the module
will be called intel-uncore-frequency.
source "drivers/platform/x86/intel_speed_select_if/Kconfig"
config SYSTEM76_ACPI
......
......@@ -105,3 +105,4 @@ obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
obj-$(CONFIG_PCENGINES_APU2) += pcengines-apuv2.o
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += intel_speed_select_if/
obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o
obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.o
......@@ -471,6 +471,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
{ KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */
{ KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } },
{ KE_IGNORE, 0x6E, }, /* Low Battery notification */
{ KE_KEY, 0x71, { KEY_F13 } }, /* General-purpose button */
{ KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */
{ KE_KEY, 0x7c, { KEY_MICMUTE } },
{ KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */
......
......@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL");
#define NOTIFY_KBD_BRTDWN 0xc5
#define NOTIFY_KBD_BRTTOGGLE 0xc7
#define NOTIFY_KBD_FBM 0x99
#define NOTIFY_KBD_TTP 0xae
#define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
......@@ -81,6 +82,10 @@ MODULE_LICENSE("GPL");
#define ASUS_FAN_BOOST_MODE_SILENT_MASK 0x02
#define ASUS_FAN_BOOST_MODES_MASK 0x03
#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT 0
#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1
#define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2
#define USB_INTEL_XUSB2PR 0xD0
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
......@@ -198,6 +203,9 @@ struct asus_wmi {
u8 fan_boost_mode_mask;
u8 fan_boost_mode;
bool throttle_thermal_policy_available;
u8 throttle_thermal_policy_mode;
// The RSOC controls the maximum charging percentage.
bool battery_rsoc_available;
......@@ -1718,6 +1726,107 @@ static ssize_t fan_boost_mode_store(struct device *dev,
// Fan boost mode: 0 - normal, 1 - overboost, 2 - silent
static DEVICE_ATTR_RW(fan_boost_mode);
/* Throttle thermal policy ****************************************************/
static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
{
u32 result;
int err;
asus->throttle_thermal_policy_available = false;
err = asus_wmi_get_devstate(asus,
ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
&result);
if (err) {
if (err == -ENODEV)
return 0;
return err;
}
if (result & ASUS_WMI_DSTS_PRESENCE_BIT)
asus->throttle_thermal_policy_available = true;
return 0;
}
static int throttle_thermal_policy_write(struct asus_wmi *asus)
{
int err;
u8 value;
u32 retval;
value = asus->throttle_thermal_policy_mode;
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
value, &retval);
if (err) {
pr_warn("Failed to set throttle thermal policy: %d\n", err);
return err;
}
if (retval != 1) {
pr_warn("Failed to set throttle thermal policy (retval): 0x%x\n",
retval);
return -EIO;
}
return 0;
}
static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
{
if (!asus->throttle_thermal_policy_available)
return 0;
asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
return throttle_thermal_policy_write(asus);
}
static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
{
u8 new_mode = asus->throttle_thermal_policy_mode + 1;
if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
asus->throttle_thermal_policy_mode = new_mode;
return throttle_thermal_policy_write(asus);
}
static ssize_t throttle_thermal_policy_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct asus_wmi *asus = dev_get_drvdata(dev);
u8 mode = asus->throttle_thermal_policy_mode;
return scnprintf(buf, PAGE_SIZE, "%d\n", mode);
}
static ssize_t throttle_thermal_policy_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int result;
u8 new_mode;
struct asus_wmi *asus = dev_get_drvdata(dev);
result = kstrtou8(buf, 10, &new_mode);
if (result < 0)
return result;
if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
return -EINVAL;
asus->throttle_thermal_policy_mode = new_mode;
throttle_thermal_policy_write(asus);
return count;
}
// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
static DEVICE_ATTR_RW(throttle_thermal_policy);
/* Backlight ******************************************************************/
static int read_backlight_power(struct asus_wmi *asus)
......@@ -1999,6 +2108,11 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
return;
}
if (asus->throttle_thermal_policy_available && code == NOTIFY_KBD_TTP) {
throttle_thermal_policy_switch_next(asus);
return;
}
if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
return;
......@@ -2149,6 +2263,7 @@ static struct attribute *platform_attributes[] = {
&dev_attr_lid_resume.attr,
&dev_attr_als_enable.attr,
&dev_attr_fan_boost_mode.attr,
&dev_attr_throttle_thermal_policy.attr,
NULL
};
......@@ -2172,6 +2287,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
devid = ASUS_WMI_DEVID_ALS_ENABLE;
else if (attr == &dev_attr_fan_boost_mode.attr)
ok = asus->fan_boost_mode_available;
else if (attr == &dev_attr_throttle_thermal_policy.attr)
ok = asus->throttle_thermal_policy_available;
if (devid != -1)
ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
......@@ -2431,6 +2548,12 @@ static int asus_wmi_add(struct platform_device *pdev)
if (err)
goto fail_fan_boost_mode;
err = throttle_thermal_policy_check_present(asus);
if (err)
goto fail_throttle_thermal_policy;
else
throttle_thermal_policy_set_default(asus);
err = asus_wmi_sysfs_init(asus->platform_device);
if (err)
goto fail_sysfs;
......@@ -2515,6 +2638,7 @@ static int asus_wmi_add(struct platform_device *pdev)
fail_input:
asus_wmi_sysfs_exit(asus->platform_device);
fail_sysfs:
fail_throttle_thermal_policy:
fail_fan_boost_mode:
fail_platform:
kfree(asus);
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/*
* Dummy driver for Intel's Image Signal Processor found on Bay and Cherry
* Trail devices. The sole purpose of this driver is to allow the ISP to
* be put in D3.
* Dummy driver for Intel's Image Signal Processor found on Bay Trail
* and Cherry Trail devices. The sole purpose of this driver is to allow
* the ISP to be put in D3.
*
* Copyright (C) 2018 Hans de Goede <hdegoede@redhat.com>
*
......@@ -36,8 +36,7 @@
static int isp_set_power(struct pci_dev *dev, bool enable)
{
unsigned long timeout;
u32 val = enable ? ISPSSPM0_IUNIT_POWER_ON :
ISPSSPM0_IUNIT_POWER_OFF;
u32 val = enable ? ISPSSPM0_IUNIT_POWER_ON : ISPSSPM0_IUNIT_POWER_OFF;
/* Write to ISPSSPM0 bit[1:0] to power on/off the IUNIT */
iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0,
......@@ -45,29 +44,25 @@ static int isp_set_power(struct pci_dev *dev, bool enable)
/*
* There should be no IUNIT access while power-down is
* in progress HW sighting: 4567865
* in progress. HW sighting: 4567865.
* Wait up to 50 ms for the IUNIT to shut down.
* And we do the same for power on.
*/
timeout = jiffies + msecs_to_jiffies(50);
while (1) {
do {
u32 tmp;
/* Wait until ISPSSPM0 bit[25:24] shows the right value */
iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0, &tmp);
tmp = (tmp & ISPSSPM0_ISPSSS_MASK) >> ISPSSPM0_ISPSSS_OFFSET;
if (tmp == val)
break;
return 0;
if (time_after(jiffies, timeout)) {
dev_err(&dev->dev, "IUNIT power-%s timeout.\n",
enable ? "on" : "off");
return -EBUSY;
}
usleep_range(1000, 2000);
}
} while (time_before(jiffies, timeout));
return 0;
dev_err(&dev->dev, "IUNIT power-%s timeout.\n", enable ? "on" : "off");
return -EBUSY;
}
static int isp_probe(struct pci_dev *dev, const struct pci_device_id *id)
......
......@@ -146,9 +146,10 @@ static int mid_pb_probe(struct platform_device *pdev)
input_set_capability(input, EV_KEY, KEY_POWER);
ddata = (struct mid_pb_ddata *)id->driver_data;
ddata = devm_kmemdup(&pdev->dev, (void *)id->driver_data,
sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENODATA;
return -ENOMEM;
ddata->dev = &pdev->dev;
ddata->irq = irq;
......
......@@ -49,7 +49,7 @@ static const struct pmc_bit_map spt_pll_map[] = {
{"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1},
{"DMIPCIE3 PLL", SPT_PMC_BIT_MPHY_CMN_LANE2},
{"SATA PLL", SPT_PMC_BIT_MPHY_CMN_LANE3},
{},
{}
};
static const struct pmc_bit_map spt_mphy_map[] = {
......@@ -69,7 +69,7 @@ static const struct pmc_bit_map spt_mphy_map[] = {
{"MPHY CORE LANE 13", SPT_PMC_BIT_MPHY_LANE13},
{"MPHY CORE LANE 14", SPT_PMC_BIT_MPHY_LANE14},
{"MPHY CORE LANE 15", SPT_PMC_BIT_MPHY_LANE15},
{},
{}
};
static const struct pmc_bit_map spt_pfear_map[] = {
......@@ -113,7 +113,12 @@ static const struct pmc_bit_map spt_pfear_map[] = {
{"CSME_SMS1", SPT_PMC_BIT_CSME_SMS1},
{"CSME_RTC", SPT_PMC_BIT_CSME_RTC},
{"CSME_PSF", SPT_PMC_BIT_CSME_PSF},
{},
{}
};
static const struct pmc_bit_map *ext_spt_pfear_map[] = {
spt_pfear_map,
NULL
};
static const struct pmc_bit_map spt_ltr_show_map[] = {
......@@ -142,7 +147,7 @@ static const struct pmc_bit_map spt_ltr_show_map[] = {
};
static const struct pmc_reg_map spt_reg_map = {
.pfear_sts = spt_pfear_map,
.pfear_sts = ext_spt_pfear_map,
.mphy_sts = spt_mphy_map,
.pll_sts = spt_pll_map,
.ltr_show_sts = spt_ltr_show_map,
......@@ -186,7 +191,10 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"SDX", BIT(4)},
{"SPE", BIT(5)},
{"Fuse", BIT(6)},
/* Reserved for Cannon Lake but valid for Ice Lake and Comet Lake */
/*
* Reserved for Cannon Lake but valid for Ice Lake, Comet Lake,
* Tiger Lake and Elkhart Lake.
*/
{"SBR8", BIT(7)},
{"CSME_FSC", BIT(0)},
......@@ -230,11 +238,22 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"HDA_PGD4", BIT(2)},
{"HDA_PGD5", BIT(3)},
{"HDA_PGD6", BIT(4)},
/* Reserved for Cannon Lake but valid for Ice Lake and Comet Lake */
/*
* Reserved for Cannon Lake but valid for Ice Lake, Comet Lake,
* Tiger Lake and ELkhart Lake.
*/
{"PSF6", BIT(5)},
{"PSF7", BIT(6)},
{"PSF8", BIT(7)},
{}
};
static const struct pmc_bit_map *ext_cnp_pfear_map[] = {
cnp_pfear_map,
NULL
};
static const struct pmc_bit_map icl_pfear_map[] = {
/* Ice Lake generation onwards only */
{"RES_65", BIT(0)},
{"RES_66", BIT(1)},
......@@ -247,6 +266,30 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{}
};
static const struct pmc_bit_map *ext_icl_pfear_map[] = {
cnp_pfear_map,
icl_pfear_map,
NULL
};
static const struct pmc_bit_map tgl_pfear_map[] = {
/* Tiger Lake and Elkhart Lake generation onwards only */
{"PSF9", BIT(0)},
{"RES_66", BIT(1)},
{"RES_67", BIT(2)},
{"RES_68", BIT(3)},
{"RES_69", BIT(4)},
{"RES_70", BIT(5)},
{"TBTLSX", BIT(6)},
{}
};
static const struct pmc_bit_map *ext_tgl_pfear_map[] = {
cnp_pfear_map,
tgl_pfear_map,
NULL
};
static const struct pmc_bit_map cnp_slps0_dbg0_map[] = {
{"AUDIO_D3", BIT(0)},
{"OTG_D3", BIT(1)},
......@@ -300,7 +343,7 @@ static const struct pmc_bit_map *cnp_slps0_dbg_maps[] = {
cnp_slps0_dbg0_map,
cnp_slps0_dbg1_map,
cnp_slps0_dbg2_map,
NULL,
NULL
};
static const struct pmc_bit_map cnp_ltr_show_map[] = {
......@@ -334,7 +377,7 @@ static const struct pmc_bit_map cnp_ltr_show_map[] = {
};
static const struct pmc_reg_map cnp_reg_map = {
.pfear_sts = cnp_pfear_map,
.pfear_sts = ext_cnp_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map,
......@@ -350,7 +393,7 @@ static const struct pmc_reg_map cnp_reg_map = {
};
static const struct pmc_reg_map icl_reg_map = {
.pfear_sts = cnp_pfear_map,
.pfear_sts = ext_icl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map,
......@@ -365,18 +408,29 @@ static const struct pmc_reg_map icl_reg_map = {
.ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED,
};
static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
{
return readb(pmcdev->regbase + offset);
}
static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map,
.slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
.regmap_length = CNP_PMC_MMIO_REG_LEN,
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
.ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
.ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
};
static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset)
{
return readl(pmcdev->regbase + reg_offset);
}
static inline void pmc_core_reg_write(struct pmc_dev *pmcdev, int
reg_offset, u32 val)
static inline void pmc_core_reg_write(struct pmc_dev *pmcdev, int reg_offset,
u32 val)
{
writel(val, pmcdev->regbase + reg_offset);
}
......@@ -412,20 +466,25 @@ static int pmc_core_check_read_lock_bit(void)
#if IS_ENABLED(CONFIG_DEBUG_FS)
static bool slps0_dbg_latch;
static void pmc_core_display_map(struct seq_file *s, int index,
u8 pf_reg, const struct pmc_bit_map *pf_map)
static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
{
return readb(pmcdev->regbase + offset);
}
static void pmc_core_display_map(struct seq_file *s, int index, int idx, int ip,
u8 pf_reg, const struct pmc_bit_map **pf_map)
{
seq_printf(s, "PCH IP: %-2d - %-32s\tState: %s\n",
index, pf_map[index].name,
pf_map[index].bit_mask & pf_reg ? "Off" : "On");
ip, pf_map[idx][index].name,
pf_map[idx][index].bit_mask & pf_reg ? "Off" : "On");
}
static int pmc_core_ppfear_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map *map = pmcdev->map->pfear_sts;
const struct pmc_bit_map **maps = pmcdev->map->pfear_sts;
u8 pf_regs[PPFEAR_MAX_NUM_ENTRIES];
int index, iter;
int index, iter, idx, ip = 0;
iter = pmcdev->map->ppfear0_offset;
......@@ -433,9 +492,12 @@ static int pmc_core_ppfear_show(struct seq_file *s, void *unused)
index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++)
pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
for (index = 0; map[index].name &&
index < pmcdev->map->ppfear_buckets * 8; index++)
pmc_core_display_map(s, index, pf_regs[index / 8], map);
for (idx = 0; maps[idx]; idx++) {
for (index = 0; maps[idx][index].name &&
index < pmcdev->map->ppfear_buckets * 8; ip++, index++)
pmc_core_display_map(s, index, idx, ip,
pf_regs[index / 8], maps);
}
return 0;
}
......@@ -561,21 +623,22 @@ static int pmc_core_pll_show(struct seq_file *s, void *unused)
}
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 ssize_t pmc_core_ltr_ignore_write(struct file *file,
const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct pmc_dev *pmcdev = &pmc;
const struct pmc_reg_map *map = pmcdev->map;
u32 val, buf_size, fd;
int err = 0;
int err;
buf_size = count < 64 ? count : 64;
mutex_lock(&pmcdev->lock);
if (kstrtou32_from_user(userbuf, buf_size, 10, &val)) {
err = -EFAULT;
goto out_unlock;
}
err = kstrtou32_from_user(userbuf, buf_size, 10, &val);
if (err)
return err;
mutex_lock(&pmcdev->lock);
if (val > map->ltr_ignore_max) {
err = -EINVAL;
......@@ -767,8 +830,9 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
debugfs_create_file("slp_s0_residency_usec", 0444, dir, pmcdev,
&pmc_core_dev_state);
debugfs_create_file("pch_ip_power_gating_status", 0444, dir, pmcdev,
&pmc_core_ppfear_fops);
if (pmcdev->map->pfear_sts)
debugfs_create_file("pch_ip_power_gating_status", 0444, dir,
pmcdev, &pmc_core_ppfear_fops);
debugfs_create_file("ltr_ignore", 0644, dir, pmcdev,
&pmc_core_ltr_ignore_ops);
......@@ -816,19 +880,22 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
INTEL_CPU_FAM6(ICELAKE_NNPI, icl_reg_map),
INTEL_CPU_FAM6(COMETLAKE, cnp_reg_map),
INTEL_CPU_FAM6(COMETLAKE_L, cnp_reg_map),
INTEL_CPU_FAM6(TIGERLAKE_L, tgl_reg_map),
INTEL_CPU_FAM6(TIGERLAKE, tgl_reg_map),
INTEL_CPU_FAM6(ATOM_TREMONT, tgl_reg_map),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_ids);
static const struct pci_device_id pmc_pci_ids[] = {
{ PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID), 0},
{ 0, },
{ PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID) },
{ }
};
/*
* This quirk can be used on those platforms where
* the platform BIOS enforces 24Mhx Crystal to shutdown
* the platform BIOS enforces 24Mhz crystal to shutdown
* before PMC can assert SLP_S0#.
*/
static int quirk_xtal_ignore(const struct dmi_system_id *id)
......
......@@ -186,6 +186,8 @@ enum ppfear_regs {
#define ICL_NUM_IP_IGN_ALLOWED 20
#define ICL_PMC_LTR_WIGIG 0x1BFC
#define TGL_NUM_IP_IGN_ALLOWED 22
struct pmc_bit_map {
const char *name;
u32 bit_mask;
......@@ -213,7 +215,7 @@ struct pmc_bit_map {
* captures them to have a common implementation.
*/
struct pmc_reg_map {
const struct pmc_bit_map *pfear_sts;
const struct pmc_bit_map **pfear_sts;
const struct pmc_bit_map *mphy_sts;
const struct pmc_bit_map *pll_sts;
const struct pmc_bit_map **slps0_dbg_maps;
......
......@@ -12,23 +12,13 @@
*/
#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_qos.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/suspend.h>
#include <asm/intel_pmc_ipc.h>
......@@ -184,11 +174,6 @@ static inline void ipc_data_writel(u32 data, u32 offset)
writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
}
static inline u8 __maybe_unused ipc_data_readb(u32 offset)
{
return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
}
static inline u32 ipc_data_readl(u32 offset)
{
return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
......@@ -210,35 +195,6 @@ static inline int is_gcr_valid(u32 offset)
return 0;
}
/**
* intel_pmc_gcr_read() - Read a 32-bit PMC GCR register
* @offset: offset of GCR register from GCR address base
* @data: data pointer for storing the register output
*
* Reads the 32-bit PMC GCR register at given offset.
*
* Return: negative value on error or 0 on success.
*/
int intel_pmc_gcr_read(u32 offset, u32 *data)
{
int ret;
spin_lock(&ipcdev.gcr_lock);
ret = is_gcr_valid(offset);
if (ret < 0) {
spin_unlock(&ipcdev.gcr_lock);
return ret;
}
*data = readl(ipcdev.gcr_mem_base + offset);
spin_unlock(&ipcdev.gcr_lock);
return 0;
}
EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
/**
* intel_pmc_gcr_read64() - Read a 64-bit PMC GCR register
* @offset: offset of GCR register from GCR address base
......@@ -268,36 +224,6 @@ int intel_pmc_gcr_read64(u32 offset, u64 *data)
}
EXPORT_SYMBOL_GPL(intel_pmc_gcr_read64);
/**
* intel_pmc_gcr_write() - Write PMC GCR register
* @offset: offset of GCR register from GCR address base
* @data: register update value
*
* Writes the PMC GCR register of given offset with given
* value.
*
* Return: negative value on error or 0 on success.
*/
int intel_pmc_gcr_write(u32 offset, u32 data)
{
int ret;
spin_lock(&ipcdev.gcr_lock);
ret = is_gcr_valid(offset);
if (ret < 0) {
spin_unlock(&ipcdev.gcr_lock);
return ret;
}
writel(data, ipcdev.gcr_mem_base + offset);
spin_unlock(&ipcdev.gcr_lock);
return 0;
}
EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
/**
* intel_pmc_gcr_update() - Update PMC GCR register bits
* @offset: offset of GCR register from GCR address base
......@@ -309,7 +235,7 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
*
* Return: negative value on error or 0 on success.
*/
int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
static int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
{
u32 new_val;
int ret = 0;
......@@ -339,7 +265,6 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
spin_unlock(&ipcdev.gcr_lock);
return ret;
}
EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
static int update_no_reboot_bit(void *priv, bool set)
{
......@@ -405,7 +330,7 @@ static int intel_pmc_ipc_check_status(void)
*
* Return: an IPC error code or 0 on success.
*/
int intel_pmc_ipc_simple_command(int cmd, int sub)
static int intel_pmc_ipc_simple_command(int cmd, int sub)
{
int ret;
......@@ -420,7 +345,6 @@ int intel_pmc_ipc_simple_command(int cmd, int sub)
return ret;
}
EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command);
/**
* intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
......@@ -437,8 +361,8 @@ EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command);
*
* Return: an IPC error code or 0 on success.
*/
int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
u32 outlen, u32 dptr, u32 sptr)
static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
u32 outlen, u32 dptr, u32 sptr)
{
u32 wbuf[4] = { 0 };
int ret;
......@@ -470,7 +394,6 @@ int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
return ret;
}
EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd);
/**
* intel_pmc_ipc_command() - IPC command with input/output data
......@@ -579,6 +502,7 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
}
return (ssize_t)count;
}
static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_ipc_simple_cmd_store);
static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
struct device_attribute *attr,
......@@ -588,8 +512,9 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
int subcmd;
int ret;
if (kstrtoul(buf, 0, &val))
return -EINVAL;
ret = kstrtoul(buf, 0, &val);
if (ret)
return ret;
if (val)
subcmd = 1;
......@@ -602,11 +527,7 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
}
return (ssize_t)count;
}
static DEVICE_ATTR(simplecmd, S_IWUSR,
NULL, intel_pmc_ipc_simple_cmd_store);
static DEVICE_ATTR(northpeak, S_IWUSR,
NULL, intel_pmc_ipc_northpeak_store);
static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_ipc_northpeak_store);
static struct attribute *intel_ipc_attrs[] = {
&dev_attr_northpeak.attr,
......@@ -618,6 +539,11 @@ static const struct attribute_group intel_ipc_group = {
.attrs = intel_ipc_attrs,
};
static const struct attribute_group *intel_ipc_groups[] = {
&intel_ipc_group,
NULL
};
static struct resource punit_res_array[] = {
/* Punit BIOS */
{
......@@ -958,18 +884,10 @@ static int ipc_plat_probe(struct platform_device *pdev)
goto err_irq;
}
ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
if (ret) {
dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
ret);
goto err_sys;
}
ipcdev.has_gcr_regs = true;
return 0;
err_sys:
devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
err_irq:
platform_device_unregister(ipcdev.tco_dev);
platform_device_unregister(ipcdev.punit_dev);
......@@ -980,7 +898,6 @@ static int ipc_plat_probe(struct platform_device *pdev)
static int ipc_plat_remove(struct platform_device *pdev)
{
sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
platform_device_unregister(ipcdev.tco_dev);
platform_device_unregister(ipcdev.punit_dev);
......@@ -995,6 +912,7 @@ static struct platform_driver ipc_plat_driver = {
.driver = {
.name = "pmc-ipc-plat",
.acpi_match_table = ACPI_PTR(ipc_acpi_ids),
.dev_groups = intel_ipc_groups,
},
};
......
This diff is collapsed.
......@@ -50,6 +50,8 @@ static const struct isst_valid_cmd_ranges isst_valid_cmds[] = {
{0x7F, 0x00, 0x0B},
{0x7F, 0x10, 0x12},
{0x7F, 0x20, 0x23},
{0x94, 0x03, 0x03},
{0x95, 0x03, 0x03},
};
static const struct isst_cmd_set_req_type isst_cmd_set_reqs[] = {
......@@ -59,6 +61,7 @@ static const struct isst_cmd_set_req_type isst_cmd_set_reqs[] = {
{0xD0, 0x03, 0x08},
{0x7F, 0x02, 0x00},
{0x7F, 0x08, 0x00},
{0x95, 0x03, 0x03},
};
struct isst_cmd {
......
......@@ -686,13 +686,14 @@ static ssize_t telem_pss_trc_verb_write(struct file *file,
u32 verbosity;
int err;
if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
return -EFAULT;
err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
if (err)
return err;
err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
if (err) {
pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
count = err;
return err;
}
return count;
......@@ -733,13 +734,14 @@ static ssize_t telem_ioss_trc_verb_write(struct file *file,
u32 verbosity;
int err;
if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
return -EFAULT;
err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
if (err)
return err;
err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
if (err) {
pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
count = err;
return err;
}
return count;
......
......@@ -1117,9 +1117,9 @@ static const struct telemetry_core_ops telm_pltops = {
static int telemetry_pltdrv_probe(struct platform_device *pdev)
{
struct resource *res0 = NULL, *res1 = NULL;
const struct x86_cpu_id *id;
int size, ret = -ENOMEM;
void __iomem *mem;
int ret;
id = x86_match_cpu(telemetry_cpu_ids);
if (!id)
......@@ -1127,50 +1127,17 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
telm_conf = (struct telemetry_plt_config *)id->driver_data;
res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res0) {
ret = -EINVAL;
goto out;
}
size = resource_size(res0);
if (!devm_request_mem_region(&pdev->dev, res0->start, size,
pdev->name)) {
ret = -EBUSY;
goto out;
}
telm_conf->pss_config.ssram_base_addr = res0->start;
telm_conf->pss_config.ssram_size = size;
mem = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mem))
return PTR_ERR(mem);
res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res1) {
ret = -EINVAL;
goto out;
}
size = resource_size(res1);
if (!devm_request_mem_region(&pdev->dev, res1->start, size,
pdev->name)) {
ret = -EBUSY;
goto out;
}
telm_conf->pss_config.regmap = mem;
telm_conf->ioss_config.ssram_base_addr = res1->start;
telm_conf->ioss_config.ssram_size = size;
mem = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(mem))
return PTR_ERR(mem);
telm_conf->pss_config.regmap = ioremap_nocache(
telm_conf->pss_config.ssram_base_addr,
telm_conf->pss_config.ssram_size);
if (!telm_conf->pss_config.regmap) {
ret = -ENOMEM;
goto out;
}
telm_conf->ioss_config.regmap = ioremap_nocache(
telm_conf->ioss_config.ssram_base_addr,
telm_conf->ioss_config.ssram_size);
if (!telm_conf->ioss_config.regmap) {
ret = -ENOMEM;
goto out;
}
telm_conf->ioss_config.regmap = mem;
mutex_init(&telm_conf->telem_lock);
mutex_init(&telm_conf->telem_trace_lock);
......@@ -1188,14 +1155,6 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
return 0;
out:
if (res0)
release_mem_region(res0->start, resource_size(res0));
if (res1)
release_mem_region(res1->start, resource_size(res1));
if (telm_conf->pss_config.regmap)
iounmap(telm_conf->pss_config.regmap);
if (telm_conf->ioss_config.regmap)
iounmap(telm_conf->ioss_config.regmap);
dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
return ret;
......@@ -1204,9 +1163,6 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
static int telemetry_pltdrv_remove(struct platform_device *pdev)
{
telemetry_clear_pltdata();
iounmap(telm_conf->pss_config.regmap);
iounmap(telm_conf->ioss_config.regmap);
return 0;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -101,6 +101,7 @@ struct mlxreg_core_data {
* @aggr_mask: group aggregation mask;
* @reg: group interrupt status register;
* @mask: group interrupt mask;
* @capability: group capability register;
* @cache: last status value for elements fro the same group;
* @count: number of available elements in the group;
* @ind: element's index inside the group;
......@@ -112,6 +113,7 @@ struct mlxreg_core_item {
u32 aggr_mask;
u32 reg;
u32 mask;
u32 capability;
u32 cache;
u8 count;
u8 ind;
......
......@@ -58,6 +58,7 @@
#define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */
#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025
#define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018
#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
/* Misc */
#define ASUS_WMI_DEVID_CAMERA 0x00060013
......
......@@ -15,7 +15,7 @@ struct process_cmd_struct {
int arg;
};
static const char *version_str = "v1.1";
static const char *version_str = "v1.2";
static const int supported_api_ver = 1;
static struct isst_if_platform_info isst_platform_info;
static char *progname;
......@@ -1384,14 +1384,10 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
goto disp_result;
}
if (auto_mode) {
if (status) {
ret = set_pbf_core_power(cpu);
if (ret)
goto disp_result;
} else {
isst_pm_qos_config(cpu, 0, 0);
}
if (auto_mode && status) {
ret = set_pbf_core_power(cpu);
if (ret)
goto disp_result;
}
ret = isst_set_pbf_fact_status(cpu, 1, status);
......@@ -1408,6 +1404,9 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
}
}
if (auto_mode && !status)
isst_pm_qos_config(cpu, 0, 0);
disp_result:
if (status)
isst_display_result(cpu, outf, "base-freq", "enable",
......@@ -1496,14 +1495,10 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
int ret;
int status = *(int *)arg4;
if (auto_mode) {
if (status) {
ret = isst_pm_qos_config(cpu, 1, 1);
if (ret)
goto disp_results;
} else {
isst_pm_qos_config(cpu, 0, 0);
}
if (auto_mode && status) {
ret = isst_pm_qos_config(cpu, 1, 1);
if (ret)
goto disp_results;
}
ret = isst_set_pbf_fact_status(cpu, 0, status);
......@@ -1524,6 +1519,9 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
ret = isst_set_trl(cpu, fact_trl);
if (ret && auto_mode)
isst_pm_qos_config(cpu, 0, 0);
} else {
if (auto_mode)
isst_pm_qos_config(cpu, 0, 0);
}
disp_results:
......@@ -1638,7 +1636,7 @@ static void set_fact_enable(int arg)
if (ret)
goto error_disp;
}
isst_display_result(i, outf, "turbo-freq --auto", "enable", 0);
isst_display_result(-1, outf, "turbo-freq --auto", "enable", 0);
}
return;
......
......@@ -6,6 +6,44 @@
#include "isst.h"
int isst_write_pm_config(int cpu, int cp_state)
{
unsigned int req, resp;
int ret;
if (cp_state)
req = BIT(16);
else
req = 0;
ret = isst_send_mbox_command(cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req,
&resp);
if (ret)
return ret;
debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", cpu, resp);
return 0;
}
int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap)
{
unsigned int resp;
int ret;
ret = isst_send_mbox_command(cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0,
&resp);
if (ret)
return ret;
debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", cpu, resp);
*cp_state = resp & BIT(16);
*cp_cap = resp & BIT(0) ? 1 : 0;
return 0;
}
int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
{
unsigned int resp;
......@@ -36,6 +74,7 @@ int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
int isst_get_ctdp_control(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level)
{
int cp_state, cp_cap;
unsigned int resp;
int ret;
......@@ -50,6 +89,15 @@ int isst_get_ctdp_control(int cpu, int config_index,
ctdp_level->fact_enabled = !!(resp & BIT(16));
ctdp_level->pbf_enabled = !!(resp & BIT(17));
ret = isst_read_pm_config(cpu, &cp_state, &cp_cap);
if (ret) {
debug_printf("cpu:%d pm_config is not supported \n", cpu);
} else {
debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d \n", cpu, cp_state, cp_cap);
ctdp_level->sst_cp_support = cp_cap;
ctdp_level->sst_cp_enabled = cp_state;
}
debug_printf(
"cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
......@@ -779,6 +827,13 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
debug_printf("Turbo-freq feature must be disabled first\n");
return -EINVAL;
}
ret = isst_write_pm_config(cpu, 0);
if (ret)
perror("isst_write_pm_config\n");
} else {
ret = isst_write_pm_config(cpu, 1);
if (ret)
perror("isst_write_pm_config\n");
}
ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
......
......@@ -418,6 +418,17 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
snprintf(value, sizeof(value), "unsupported");
format_and_print(outf, base_level + 4, header, value);
snprintf(header, sizeof(header),
"speed-select-core-power");
if (ctdp_level->sst_cp_support) {
if (ctdp_level->sst_cp_enabled)
snprintf(value, sizeof(value), "enabled");
else
snprintf(value, sizeof(value), "disabled");
} else
snprintf(value, sizeof(value), "unsupported");
format_and_print(outf, base_level + 4, header, value);
if (is_clx_n_platform()) {
if (ctdp_level->pbf_support)
_isst_pbf_display_information(cpu, outf,
......@@ -634,13 +645,15 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
char header[256];
char value[256];
snprintf(header, sizeof(header), "package-%d",
get_physical_package_id(cpu));
format_and_print(outf, 1, header, NULL);
snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
format_and_print(outf, 2, header, NULL);
snprintf(header, sizeof(header), "cpu-%d", cpu);
format_and_print(outf, 3, header, NULL);
if (cpu >= 0) {
snprintf(header, sizeof(header), "package-%d",
get_physical_package_id(cpu));
format_and_print(outf, 1, header, NULL);
snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
format_and_print(outf, 2, header, NULL);
snprintf(header, sizeof(header), "cpu-%d", cpu);
format_and_print(outf, 3, header, NULL);
}
snprintf(header, sizeof(header), "%s", feature);
format_and_print(outf, 4, header, NULL);
snprintf(header, sizeof(header), "%s", cmd);
......
......@@ -69,6 +69,10 @@
#define PM_CLOS_OFFSET 0x08
#define PQR_ASSOC_OFFSET 0x20
#define READ_PM_CONFIG 0x94
#define WRITE_PM_CONFIG 0x95
#define PM_FEATURE 0x03
#define DISP_FREQ_MULTIPLIER 100
struct isst_clos_config {
......@@ -119,6 +123,8 @@ struct isst_pkg_ctdp_level_info {
int pbf_support;
int fact_enabled;
int pbf_enabled;
int sst_cp_support;
int sst_cp_enabled;
int tdp_ratio;
int active;
int tdp_control;
......
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