cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ics932s401.c (12902B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * A driver for the Integrated Circuits ICS932S401
      4 * Copyright (C) 2008 IBM
      5 *
      6 * Author: Darrick J. Wong <darrick.wong@oracle.com>
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/jiffies.h>
     11#include <linux/i2c.h>
     12#include <linux/err.h>
     13#include <linux/mutex.h>
     14#include <linux/delay.h>
     15#include <linux/log2.h>
     16#include <linux/slab.h>
     17
     18/* Addresses to scan */
     19static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
     20
     21/* ICS932S401 registers */
     22#define ICS932S401_REG_CFG2			0x01
     23#define		ICS932S401_CFG1_SPREAD		0x01
     24#define ICS932S401_REG_CFG7			0x06
     25#define		ICS932S401_FS_MASK		0x07
     26#define	ICS932S401_REG_VENDOR_REV		0x07
     27#define		ICS932S401_VENDOR		1
     28#define		ICS932S401_VENDOR_MASK		0x0F
     29#define		ICS932S401_REV			4
     30#define		ICS932S401_REV_SHIFT		4
     31#define ICS932S401_REG_DEVICE			0x09
     32#define		ICS932S401_DEVICE		11
     33#define	ICS932S401_REG_CTRL			0x0A
     34#define		ICS932S401_MN_ENABLED		0x80
     35#define		ICS932S401_CPU_ALT		0x04
     36#define		ICS932S401_SRC_ALT		0x08
     37#define ICS932S401_REG_CPU_M_CTRL		0x0B
     38#define		ICS932S401_M_MASK		0x3F
     39#define	ICS932S401_REG_CPU_N_CTRL		0x0C
     40#define	ICS932S401_REG_CPU_SPREAD1		0x0D
     41#define ICS932S401_REG_CPU_SPREAD2		0x0E
     42#define		ICS932S401_SPREAD_MASK		0x7FFF
     43#define ICS932S401_REG_SRC_M_CTRL		0x0F
     44#define ICS932S401_REG_SRC_N_CTRL		0x10
     45#define	ICS932S401_REG_SRC_SPREAD1		0x11
     46#define ICS932S401_REG_SRC_SPREAD2		0x12
     47#define ICS932S401_REG_CPU_DIVISOR		0x13
     48#define		ICS932S401_CPU_DIVISOR_SHIFT	4
     49#define ICS932S401_REG_PCISRC_DIVISOR		0x14
     50#define		ICS932S401_SRC_DIVISOR_MASK	0x0F
     51#define		ICS932S401_PCI_DIVISOR_SHIFT	4
     52
     53/* Base clock is 14.318MHz */
     54#define BASE_CLOCK				14318
     55
     56#define NUM_REGS				21
     57#define NUM_MIRRORED_REGS			15
     58
     59static int regs_to_copy[NUM_MIRRORED_REGS] = {
     60	ICS932S401_REG_CFG2,
     61	ICS932S401_REG_CFG7,
     62	ICS932S401_REG_VENDOR_REV,
     63	ICS932S401_REG_DEVICE,
     64	ICS932S401_REG_CTRL,
     65	ICS932S401_REG_CPU_M_CTRL,
     66	ICS932S401_REG_CPU_N_CTRL,
     67	ICS932S401_REG_CPU_SPREAD1,
     68	ICS932S401_REG_CPU_SPREAD2,
     69	ICS932S401_REG_SRC_M_CTRL,
     70	ICS932S401_REG_SRC_N_CTRL,
     71	ICS932S401_REG_SRC_SPREAD1,
     72	ICS932S401_REG_SRC_SPREAD2,
     73	ICS932S401_REG_CPU_DIVISOR,
     74	ICS932S401_REG_PCISRC_DIVISOR,
     75};
     76
     77/* How often do we reread sensors values? (In jiffies) */
     78#define SENSOR_REFRESH_INTERVAL	(2 * HZ)
     79
     80/* How often do we reread sensor limit values? (In jiffies) */
     81#define LIMIT_REFRESH_INTERVAL	(60 * HZ)
     82
     83struct ics932s401_data {
     84	struct attribute_group	attrs;
     85	struct mutex		lock;
     86	char			sensors_valid;
     87	unsigned long		sensors_last_updated;	/* In jiffies */
     88
     89	u8			regs[NUM_REGS];
     90};
     91
     92static int ics932s401_probe(struct i2c_client *client,
     93			 const struct i2c_device_id *id);
     94static int ics932s401_detect(struct i2c_client *client,
     95			  struct i2c_board_info *info);
     96static int ics932s401_remove(struct i2c_client *client);
     97
     98static const struct i2c_device_id ics932s401_id[] = {
     99	{ "ics932s401", 0 },
    100	{ }
    101};
    102MODULE_DEVICE_TABLE(i2c, ics932s401_id);
    103
    104static struct i2c_driver ics932s401_driver = {
    105	.class		= I2C_CLASS_HWMON,
    106	.driver = {
    107		.name	= "ics932s401",
    108	},
    109	.probe		= ics932s401_probe,
    110	.remove		= ics932s401_remove,
    111	.id_table	= ics932s401_id,
    112	.detect		= ics932s401_detect,
    113	.address_list	= normal_i2c,
    114};
    115
    116static struct ics932s401_data *ics932s401_update_device(struct device *dev)
    117{
    118	struct i2c_client *client = to_i2c_client(dev);
    119	struct ics932s401_data *data = i2c_get_clientdata(client);
    120	unsigned long local_jiffies = jiffies;
    121	int i, temp;
    122
    123	mutex_lock(&data->lock);
    124	if (time_before(local_jiffies, data->sensors_last_updated +
    125		SENSOR_REFRESH_INTERVAL)
    126		&& data->sensors_valid)
    127		goto out;
    128
    129	/*
    130	 * Each register must be read as a word and then right shifted 8 bits.
    131	 * Not really sure why this is; setting the "byte count programming"
    132	 * register to 1 does not fix this problem.
    133	 */
    134	for (i = 0; i < NUM_MIRRORED_REGS; i++) {
    135		temp = i2c_smbus_read_word_data(client, regs_to_copy[i]);
    136		if (temp < 0)
    137			temp = 0;
    138		data->regs[regs_to_copy[i]] = temp >> 8;
    139	}
    140
    141	data->sensors_last_updated = local_jiffies;
    142	data->sensors_valid = 1;
    143
    144out:
    145	mutex_unlock(&data->lock);
    146	return data;
    147}
    148
    149static ssize_t show_spread_enabled(struct device *dev,
    150				   struct device_attribute *devattr,
    151				   char *buf)
    152{
    153	struct ics932s401_data *data = ics932s401_update_device(dev);
    154
    155	if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)
    156		return sprintf(buf, "1\n");
    157
    158	return sprintf(buf, "0\n");
    159}
    160
    161/* bit to cpu khz map */
    162static const int fs_speeds[] = {
    163	266666,
    164	133333,
    165	200000,
    166	166666,
    167	333333,
    168	100000,
    169	400000,
    170	0,
    171};
    172
    173/* clock divisor map */
    174static const int divisors[] = {2, 3, 5, 15, 4, 6, 10, 30, 8, 12, 20, 60, 16,
    175			       24, 40, 120};
    176
    177/* Calculate CPU frequency from the M/N registers. */
    178static int calculate_cpu_freq(struct ics932s401_data *data)
    179{
    180	int m, n, freq;
    181
    182	m = data->regs[ICS932S401_REG_CPU_M_CTRL] & ICS932S401_M_MASK;
    183	n = data->regs[ICS932S401_REG_CPU_N_CTRL];
    184
    185	/* Pull in bits 8 & 9 from the M register */
    186	n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x80) << 1;
    187	n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x40) << 3;
    188
    189	freq = BASE_CLOCK * (n + 8) / (m + 2);
    190	freq /= divisors[data->regs[ICS932S401_REG_CPU_DIVISOR] >>
    191			 ICS932S401_CPU_DIVISOR_SHIFT];
    192
    193	return freq;
    194}
    195
    196static ssize_t show_cpu_clock(struct device *dev,
    197			      struct device_attribute *devattr,
    198			      char *buf)
    199{
    200	struct ics932s401_data *data = ics932s401_update_device(dev);
    201
    202	return sprintf(buf, "%d\n", calculate_cpu_freq(data));
    203}
    204
    205static ssize_t show_cpu_clock_sel(struct device *dev,
    206				  struct device_attribute *devattr,
    207				  char *buf)
    208{
    209	struct ics932s401_data *data = ics932s401_update_device(dev);
    210	int freq;
    211
    212	if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
    213		freq = calculate_cpu_freq(data);
    214	else {
    215		/* Freq is neatly wrapped up for us */
    216		int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK;
    217
    218		freq = fs_speeds[fid];
    219		if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) {
    220			switch (freq) {
    221			case 166666:
    222				freq = 160000;
    223				break;
    224			case 333333:
    225				freq = 320000;
    226				break;
    227			}
    228		}
    229	}
    230
    231	return sprintf(buf, "%d\n", freq);
    232}
    233
    234/* Calculate SRC frequency from the M/N registers. */
    235static int calculate_src_freq(struct ics932s401_data *data)
    236{
    237	int m, n, freq;
    238
    239	m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;
    240	n = data->regs[ICS932S401_REG_SRC_N_CTRL];
    241
    242	/* Pull in bits 8 & 9 from the M register */
    243	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;
    244	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;
    245
    246	freq = BASE_CLOCK * (n + 8) / (m + 2);
    247	freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] &
    248			 ICS932S401_SRC_DIVISOR_MASK];
    249
    250	return freq;
    251}
    252
    253static ssize_t show_src_clock(struct device *dev,
    254			      struct device_attribute *devattr,
    255			      char *buf)
    256{
    257	struct ics932s401_data *data = ics932s401_update_device(dev);
    258
    259	return sprintf(buf, "%d\n", calculate_src_freq(data));
    260}
    261
    262static ssize_t show_src_clock_sel(struct device *dev,
    263				  struct device_attribute *devattr,
    264				  char *buf)
    265{
    266	struct ics932s401_data *data = ics932s401_update_device(dev);
    267	int freq;
    268
    269	if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
    270		freq = calculate_src_freq(data);
    271	else
    272		/* Freq is neatly wrapped up for us */
    273		if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT &&
    274		    data->regs[ICS932S401_REG_CTRL] & ICS932S401_SRC_ALT)
    275			freq = 96000;
    276		else
    277			freq = 100000;
    278
    279	return sprintf(buf, "%d\n", freq);
    280}
    281
    282/* Calculate PCI frequency from the SRC M/N registers. */
    283static int calculate_pci_freq(struct ics932s401_data *data)
    284{
    285	int m, n, freq;
    286
    287	m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;
    288	n = data->regs[ICS932S401_REG_SRC_N_CTRL];
    289
    290	/* Pull in bits 8 & 9 from the M register */
    291	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;
    292	n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;
    293
    294	freq = BASE_CLOCK * (n + 8) / (m + 2);
    295	freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] >>
    296			 ICS932S401_PCI_DIVISOR_SHIFT];
    297
    298	return freq;
    299}
    300
    301static ssize_t show_pci_clock(struct device *dev,
    302			      struct device_attribute *devattr,
    303			      char *buf)
    304{
    305	struct ics932s401_data *data = ics932s401_update_device(dev);
    306
    307	return sprintf(buf, "%d\n", calculate_pci_freq(data));
    308}
    309
    310static ssize_t show_pci_clock_sel(struct device *dev,
    311				  struct device_attribute *devattr,
    312				  char *buf)
    313{
    314	struct ics932s401_data *data = ics932s401_update_device(dev);
    315	int freq;
    316
    317	if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
    318		freq = calculate_pci_freq(data);
    319	else
    320		freq = 33333;
    321
    322	return sprintf(buf, "%d\n", freq);
    323}
    324
    325static ssize_t show_value(struct device *dev,
    326			  struct device_attribute *devattr,
    327			  char *buf);
    328
    329static ssize_t show_spread(struct device *dev,
    330			   struct device_attribute *devattr,
    331			   char *buf);
    332
    333static DEVICE_ATTR(spread_enabled, S_IRUGO, show_spread_enabled, NULL);
    334static DEVICE_ATTR(cpu_clock_selection, S_IRUGO, show_cpu_clock_sel, NULL);
    335static DEVICE_ATTR(cpu_clock, S_IRUGO, show_cpu_clock, NULL);
    336static DEVICE_ATTR(src_clock_selection, S_IRUGO, show_src_clock_sel, NULL);
    337static DEVICE_ATTR(src_clock, S_IRUGO, show_src_clock, NULL);
    338static DEVICE_ATTR(pci_clock_selection, S_IRUGO, show_pci_clock_sel, NULL);
    339static DEVICE_ATTR(pci_clock, S_IRUGO, show_pci_clock, NULL);
    340static DEVICE_ATTR(usb_clock, S_IRUGO, show_value, NULL);
    341static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL);
    342static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL);
    343static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL);
    344
    345static struct attribute *ics932s401_attr[] = {
    346	&dev_attr_spread_enabled.attr,
    347	&dev_attr_cpu_clock_selection.attr,
    348	&dev_attr_cpu_clock.attr,
    349	&dev_attr_src_clock_selection.attr,
    350	&dev_attr_src_clock.attr,
    351	&dev_attr_pci_clock_selection.attr,
    352	&dev_attr_pci_clock.attr,
    353	&dev_attr_usb_clock.attr,
    354	&dev_attr_ref_clock.attr,
    355	&dev_attr_cpu_spread.attr,
    356	&dev_attr_src_spread.attr,
    357	NULL
    358};
    359
    360static ssize_t show_value(struct device *dev,
    361			  struct device_attribute *devattr,
    362			  char *buf)
    363{
    364	int x;
    365
    366	if (devattr == &dev_attr_usb_clock)
    367		x = 48000;
    368	else if (devattr == &dev_attr_ref_clock)
    369		x = BASE_CLOCK;
    370	else
    371		BUG();
    372
    373	return sprintf(buf, "%d\n", x);
    374}
    375
    376static ssize_t show_spread(struct device *dev,
    377			   struct device_attribute *devattr,
    378			   char *buf)
    379{
    380	struct ics932s401_data *data = ics932s401_update_device(dev);
    381	int reg;
    382	unsigned long val;
    383
    384	if (!(data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD))
    385		return sprintf(buf, "0%%\n");
    386
    387	if (devattr == &dev_attr_src_spread)
    388		reg = ICS932S401_REG_SRC_SPREAD1;
    389	else if (devattr == &dev_attr_cpu_spread)
    390		reg = ICS932S401_REG_CPU_SPREAD1;
    391	else
    392		BUG();
    393
    394	val = data->regs[reg] | (data->regs[reg + 1] << 8);
    395	val &= ICS932S401_SPREAD_MASK;
    396
    397	/* Scale 0..2^14 to -0.5. */
    398	val = 500000 * val / 16384;
    399	return sprintf(buf, "-0.%lu%%\n", val);
    400}
    401
    402/* Return 0 if detection is successful, -ENODEV otherwise */
    403static int ics932s401_detect(struct i2c_client *client,
    404			  struct i2c_board_info *info)
    405{
    406	struct i2c_adapter *adapter = client->adapter;
    407	int vendor, device, revision;
    408
    409	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
    410		return -ENODEV;
    411
    412	vendor = i2c_smbus_read_word_data(client, ICS932S401_REG_VENDOR_REV);
    413	vendor >>= 8;
    414	revision = vendor >> ICS932S401_REV_SHIFT;
    415	vendor &= ICS932S401_VENDOR_MASK;
    416	if (vendor != ICS932S401_VENDOR)
    417		return -ENODEV;
    418
    419	device = i2c_smbus_read_word_data(client, ICS932S401_REG_DEVICE);
    420	device >>= 8;
    421	if (device != ICS932S401_DEVICE)
    422		return -ENODEV;
    423
    424	if (revision != ICS932S401_REV)
    425		dev_info(&adapter->dev, "Unknown revision %d\n", revision);
    426
    427	strlcpy(info->type, "ics932s401", I2C_NAME_SIZE);
    428
    429	return 0;
    430}
    431
    432static int ics932s401_probe(struct i2c_client *client,
    433			 const struct i2c_device_id *id)
    434{
    435	struct ics932s401_data *data;
    436	int err;
    437
    438	data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL);
    439	if (!data) {
    440		err = -ENOMEM;
    441		goto exit;
    442	}
    443
    444	i2c_set_clientdata(client, data);
    445	mutex_init(&data->lock);
    446
    447	dev_info(&client->dev, "%s chip found\n", client->name);
    448
    449	/* Register sysfs hooks */
    450	data->attrs.attrs = ics932s401_attr;
    451	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
    452	if (err)
    453		goto exit_free;
    454
    455	return 0;
    456
    457exit_free:
    458	kfree(data);
    459exit:
    460	return err;
    461}
    462
    463static int ics932s401_remove(struct i2c_client *client)
    464{
    465	struct ics932s401_data *data = i2c_get_clientdata(client);
    466
    467	sysfs_remove_group(&client->dev.kobj, &data->attrs);
    468	kfree(data);
    469	return 0;
    470}
    471
    472module_i2c_driver(ics932s401_driver);
    473
    474MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");
    475MODULE_DESCRIPTION("ICS932S401 driver");
    476MODULE_LICENSE("GPL");
    477
    478/* IBM IntelliStation Z30 */
    479MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*");
    480MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*");
    481
    482/* IBM x3650/x3550 */
    483MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650*");
    484MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550*");