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

brcmstb-avs-cpufreq.c (20602B)


      1/*
      2 * CPU frequency scaling for Broadcom SoCs with AVS firmware that
      3 * supports DVS or DVFS
      4 *
      5 * Copyright (c) 2016 Broadcom
      6 *
      7 * This program is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU General Public License as
      9 * published by the Free Software Foundation version 2.
     10 *
     11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
     12 * kind, whether express or implied; without even the implied warranty
     13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 */
     16
     17/*
     18 * "AVS" is the name of a firmware developed at Broadcom. It derives
     19 * its name from the technique called "Adaptive Voltage Scaling".
     20 * Adaptive voltage scaling was the original purpose of this firmware.
     21 * The AVS firmware still supports "AVS mode", where all it does is
     22 * adaptive voltage scaling. However, on some newer Broadcom SoCs, the
     23 * AVS Firmware, despite its unchanged name, also supports DFS mode and
     24 * DVFS mode.
     25 *
     26 * In the context of this document and the related driver, "AVS" by
     27 * itself always means the Broadcom firmware and never refers to the
     28 * technique called "Adaptive Voltage Scaling".
     29 *
     30 * The Broadcom STB AVS CPUfreq driver provides voltage and frequency
     31 * scaling on Broadcom SoCs using AVS firmware with support for DFS and
     32 * DVFS. The AVS firmware is running on its own co-processor. The
     33 * driver supports both uniprocessor (UP) and symmetric multiprocessor
     34 * (SMP) systems which share clock and voltage across all CPUs.
     35 *
     36 * Actual voltage and frequency scaling is done solely by the AVS
     37 * firmware. This driver does not change frequency or voltage itself.
     38 * It provides a standard CPUfreq interface to the rest of the kernel
     39 * and to userland. It interfaces with the AVS firmware to effect the
     40 * requested changes and to report back the current system status in a
     41 * way that is expected by existing tools.
     42 */
     43
     44#include <linux/cpufreq.h>
     45#include <linux/delay.h>
     46#include <linux/interrupt.h>
     47#include <linux/io.h>
     48#include <linux/module.h>
     49#include <linux/of_address.h>
     50#include <linux/platform_device.h>
     51#include <linux/semaphore.h>
     52
     53/* Max number of arguments AVS calls take */
     54#define AVS_MAX_CMD_ARGS	4
     55/*
     56 * This macro is used to generate AVS parameter register offsets. For
     57 * x >= AVS_MAX_CMD_ARGS, it returns 0 to protect against accidental memory
     58 * access outside of the parameter range. (Offset 0 is the first parameter.)
     59 */
     60#define AVS_PARAM_MULT(x)	((x) < AVS_MAX_CMD_ARGS ? (x) : 0)
     61
     62/* AVS Mailbox Register offsets */
     63#define AVS_MBOX_COMMAND	0x00
     64#define AVS_MBOX_STATUS		0x04
     65#define AVS_MBOX_VOLTAGE0	0x08
     66#define AVS_MBOX_TEMP0		0x0c
     67#define AVS_MBOX_PV0		0x10
     68#define AVS_MBOX_MV0		0x14
     69#define AVS_MBOX_PARAM(x)	(0x18 + AVS_PARAM_MULT(x) * sizeof(u32))
     70#define AVS_MBOX_REVISION	0x28
     71#define AVS_MBOX_PSTATE		0x2c
     72#define AVS_MBOX_HEARTBEAT	0x30
     73#define AVS_MBOX_MAGIC		0x34
     74#define AVS_MBOX_SIGMA_HVT	0x38
     75#define AVS_MBOX_SIGMA_SVT	0x3c
     76#define AVS_MBOX_VOLTAGE1	0x40
     77#define AVS_MBOX_TEMP1		0x44
     78#define AVS_MBOX_PV1		0x48
     79#define AVS_MBOX_MV1		0x4c
     80#define AVS_MBOX_FREQUENCY	0x50
     81
     82/* AVS Commands */
     83#define AVS_CMD_AVAILABLE	0x00
     84#define AVS_CMD_DISABLE		0x10
     85#define AVS_CMD_ENABLE		0x11
     86#define AVS_CMD_S2_ENTER	0x12
     87#define AVS_CMD_S2_EXIT		0x13
     88#define AVS_CMD_BBM_ENTER	0x14
     89#define AVS_CMD_BBM_EXIT	0x15
     90#define AVS_CMD_S3_ENTER	0x16
     91#define AVS_CMD_S3_EXIT		0x17
     92#define AVS_CMD_BALANCE		0x18
     93/* PMAP and P-STATE commands */
     94#define AVS_CMD_GET_PMAP	0x30
     95#define AVS_CMD_SET_PMAP	0x31
     96#define AVS_CMD_GET_PSTATE	0x40
     97#define AVS_CMD_SET_PSTATE	0x41
     98
     99/* Different modes AVS supports (for GET_PMAP/SET_PMAP) */
    100#define AVS_MODE_AVS		0x0
    101#define AVS_MODE_DFS		0x1
    102#define AVS_MODE_DVS		0x2
    103#define AVS_MODE_DVFS		0x3
    104
    105/*
    106 * PMAP parameter p1
    107 * unused:31-24, mdiv_p0:23-16, unused:15-14, pdiv:13-10 , ndiv_int:9-0
    108 */
    109#define NDIV_INT_SHIFT		0
    110#define NDIV_INT_MASK		0x3ff
    111#define PDIV_SHIFT		10
    112#define PDIV_MASK		0xf
    113#define MDIV_P0_SHIFT		16
    114#define MDIV_P0_MASK		0xff
    115/*
    116 * PMAP parameter p2
    117 * mdiv_p4:31-24, mdiv_p3:23-16, mdiv_p2:15:8, mdiv_p1:7:0
    118 */
    119#define MDIV_P1_SHIFT		0
    120#define MDIV_P1_MASK		0xff
    121#define MDIV_P2_SHIFT		8
    122#define MDIV_P2_MASK		0xff
    123#define MDIV_P3_SHIFT		16
    124#define MDIV_P3_MASK		0xff
    125#define MDIV_P4_SHIFT		24
    126#define MDIV_P4_MASK		0xff
    127
    128/* Different P-STATES AVS supports (for GET_PSTATE/SET_PSTATE) */
    129#define AVS_PSTATE_P0		0x0
    130#define AVS_PSTATE_P1		0x1
    131#define AVS_PSTATE_P2		0x2
    132#define AVS_PSTATE_P3		0x3
    133#define AVS_PSTATE_P4		0x4
    134#define AVS_PSTATE_MAX		AVS_PSTATE_P4
    135
    136/* CPU L2 Interrupt Controller Registers */
    137#define AVS_CPU_L2_SET0		0x04
    138#define AVS_CPU_L2_INT_MASK	BIT(31)
    139
    140/* AVS Command Status Values */
    141#define AVS_STATUS_CLEAR	0x00
    142/* Command/notification accepted */
    143#define AVS_STATUS_SUCCESS	0xf0
    144/* Command/notification rejected */
    145#define AVS_STATUS_FAILURE	0xff
    146/* Invalid command/notification (unknown) */
    147#define AVS_STATUS_INVALID	0xf1
    148/* Non-AVS modes are not supported */
    149#define AVS_STATUS_NO_SUPP	0xf2
    150/* Cannot set P-State until P-Map supplied */
    151#define AVS_STATUS_NO_MAP	0xf3
    152/* Cannot change P-Map after initial P-Map set */
    153#define AVS_STATUS_MAP_SET	0xf4
    154/* Max AVS status; higher numbers are used for debugging */
    155#define AVS_STATUS_MAX		0xff
    156
    157/* Other AVS related constants */
    158#define AVS_LOOP_LIMIT		10000
    159#define AVS_TIMEOUT		300 /* in ms; expected completion is < 10ms */
    160#define AVS_FIRMWARE_MAGIC	0xa11600d1
    161
    162#define BRCM_AVS_CPUFREQ_PREFIX	"brcmstb-avs"
    163#define BRCM_AVS_CPUFREQ_NAME	BRCM_AVS_CPUFREQ_PREFIX "-cpufreq"
    164#define BRCM_AVS_CPU_DATA	"brcm,avs-cpu-data-mem"
    165#define BRCM_AVS_CPU_INTR	"brcm,avs-cpu-l2-intr"
    166#define BRCM_AVS_HOST_INTR	"sw_intr"
    167
    168struct pmap {
    169	unsigned int mode;
    170	unsigned int p1;
    171	unsigned int p2;
    172	unsigned int state;
    173};
    174
    175struct private_data {
    176	void __iomem *base;
    177	void __iomem *avs_intr_base;
    178	struct device *dev;
    179	struct completion done;
    180	struct semaphore sem;
    181	struct pmap pmap;
    182	int host_irq;
    183};
    184
    185static void __iomem *__map_region(const char *name)
    186{
    187	struct device_node *np;
    188	void __iomem *ptr;
    189
    190	np = of_find_compatible_node(NULL, NULL, name);
    191	if (!np)
    192		return NULL;
    193
    194	ptr = of_iomap(np, 0);
    195	of_node_put(np);
    196
    197	return ptr;
    198}
    199
    200static unsigned long wait_for_avs_command(struct private_data *priv,
    201					  unsigned long timeout)
    202{
    203	unsigned long time_left = 0;
    204	u32 val;
    205
    206	/* Event driven, wait for the command interrupt */
    207	if (priv->host_irq >= 0)
    208		return wait_for_completion_timeout(&priv->done,
    209						   msecs_to_jiffies(timeout));
    210
    211	/* Polling for command completion */
    212	do {
    213		time_left = timeout;
    214		val = readl(priv->base + AVS_MBOX_STATUS);
    215		if (val)
    216			break;
    217
    218		usleep_range(1000, 2000);
    219	} while (--timeout);
    220
    221	return time_left;
    222}
    223
    224static int __issue_avs_command(struct private_data *priv, unsigned int cmd,
    225			       unsigned int num_in, unsigned int num_out,
    226			       u32 args[])
    227{
    228	void __iomem *base = priv->base;
    229	unsigned long time_left;
    230	unsigned int i;
    231	int ret;
    232	u32 val;
    233
    234	ret = down_interruptible(&priv->sem);
    235	if (ret)
    236		return ret;
    237
    238	/*
    239	 * Make sure no other command is currently running: cmd is 0 if AVS
    240	 * co-processor is idle. Due to the guard above, we should almost never
    241	 * have to wait here.
    242	 */
    243	for (i = 0, val = 1; val != 0 && i < AVS_LOOP_LIMIT; i++)
    244		val = readl(base + AVS_MBOX_COMMAND);
    245
    246	/* Give the caller a chance to retry if AVS is busy. */
    247	if (i == AVS_LOOP_LIMIT) {
    248		ret = -EAGAIN;
    249		goto out;
    250	}
    251
    252	/* Clear status before we begin. */
    253	writel(AVS_STATUS_CLEAR, base + AVS_MBOX_STATUS);
    254
    255	/* Provide input parameters */
    256	for (i = 0; i < num_in; i++)
    257		writel(args[i], base + AVS_MBOX_PARAM(i));
    258
    259	/* Protect from spurious interrupts. */
    260	reinit_completion(&priv->done);
    261
    262	/* Now issue the command & tell firmware to wake up to process it. */
    263	writel(cmd, base + AVS_MBOX_COMMAND);
    264	writel(AVS_CPU_L2_INT_MASK, priv->avs_intr_base + AVS_CPU_L2_SET0);
    265
    266	/* Wait for AVS co-processor to finish processing the command. */
    267	time_left = wait_for_avs_command(priv, AVS_TIMEOUT);
    268
    269	/*
    270	 * If the AVS status is not in the expected range, it means AVS didn't
    271	 * complete our command in time, and we return an error. Also, if there
    272	 * is no "time left", we timed out waiting for the interrupt.
    273	 */
    274	val = readl(base + AVS_MBOX_STATUS);
    275	if (time_left == 0 || val == 0 || val > AVS_STATUS_MAX) {
    276		dev_err(priv->dev, "AVS command %#x didn't complete in time\n",
    277			cmd);
    278		dev_err(priv->dev, "    Time left: %u ms, AVS status: %#x\n",
    279			jiffies_to_msecs(time_left), val);
    280		ret = -ETIMEDOUT;
    281		goto out;
    282	}
    283
    284	/* Process returned values */
    285	for (i = 0; i < num_out; i++)
    286		args[i] = readl(base + AVS_MBOX_PARAM(i));
    287
    288	/* Clear status to tell AVS co-processor we are done. */
    289	writel(AVS_STATUS_CLEAR, base + AVS_MBOX_STATUS);
    290
    291	/* Convert firmware errors to errno's as much as possible. */
    292	switch (val) {
    293	case AVS_STATUS_INVALID:
    294		ret = -EINVAL;
    295		break;
    296	case AVS_STATUS_NO_SUPP:
    297		ret = -ENOTSUPP;
    298		break;
    299	case AVS_STATUS_NO_MAP:
    300		ret = -ENOENT;
    301		break;
    302	case AVS_STATUS_MAP_SET:
    303		ret = -EEXIST;
    304		break;
    305	case AVS_STATUS_FAILURE:
    306		ret = -EIO;
    307		break;
    308	}
    309
    310out:
    311	up(&priv->sem);
    312
    313	return ret;
    314}
    315
    316static irqreturn_t irq_handler(int irq, void *data)
    317{
    318	struct private_data *priv = data;
    319
    320	/* AVS command completed execution. Wake up __issue_avs_command(). */
    321	complete(&priv->done);
    322
    323	return IRQ_HANDLED;
    324}
    325
    326static char *brcm_avs_mode_to_string(unsigned int mode)
    327{
    328	switch (mode) {
    329	case AVS_MODE_AVS:
    330		return "AVS";
    331	case AVS_MODE_DFS:
    332		return "DFS";
    333	case AVS_MODE_DVS:
    334		return "DVS";
    335	case AVS_MODE_DVFS:
    336		return "DVFS";
    337	}
    338	return NULL;
    339}
    340
    341static void brcm_avs_parse_p1(u32 p1, unsigned int *mdiv_p0, unsigned int *pdiv,
    342			      unsigned int *ndiv)
    343{
    344	*mdiv_p0 = (p1 >> MDIV_P0_SHIFT) & MDIV_P0_MASK;
    345	*pdiv = (p1 >> PDIV_SHIFT) & PDIV_MASK;
    346	*ndiv = (p1 >> NDIV_INT_SHIFT) & NDIV_INT_MASK;
    347}
    348
    349static void brcm_avs_parse_p2(u32 p2, unsigned int *mdiv_p1,
    350			      unsigned int *mdiv_p2, unsigned int *mdiv_p3,
    351			      unsigned int *mdiv_p4)
    352{
    353	*mdiv_p4 = (p2 >> MDIV_P4_SHIFT) & MDIV_P4_MASK;
    354	*mdiv_p3 = (p2 >> MDIV_P3_SHIFT) & MDIV_P3_MASK;
    355	*mdiv_p2 = (p2 >> MDIV_P2_SHIFT) & MDIV_P2_MASK;
    356	*mdiv_p1 = (p2 >> MDIV_P1_SHIFT) & MDIV_P1_MASK;
    357}
    358
    359static int brcm_avs_get_pmap(struct private_data *priv, struct pmap *pmap)
    360{
    361	u32 args[AVS_MAX_CMD_ARGS];
    362	int ret;
    363
    364	ret = __issue_avs_command(priv, AVS_CMD_GET_PMAP, 0, 4, args);
    365	if (ret || !pmap)
    366		return ret;
    367
    368	pmap->mode = args[0];
    369	pmap->p1 = args[1];
    370	pmap->p2 = args[2];
    371	pmap->state = args[3];
    372
    373	return 0;
    374}
    375
    376static int brcm_avs_set_pmap(struct private_data *priv, struct pmap *pmap)
    377{
    378	u32 args[AVS_MAX_CMD_ARGS];
    379
    380	args[0] = pmap->mode;
    381	args[1] = pmap->p1;
    382	args[2] = pmap->p2;
    383	args[3] = pmap->state;
    384
    385	return __issue_avs_command(priv, AVS_CMD_SET_PMAP, 4, 0, args);
    386}
    387
    388static int brcm_avs_get_pstate(struct private_data *priv, unsigned int *pstate)
    389{
    390	u32 args[AVS_MAX_CMD_ARGS];
    391	int ret;
    392
    393	ret = __issue_avs_command(priv, AVS_CMD_GET_PSTATE, 0, 1, args);
    394	if (ret)
    395		return ret;
    396	*pstate = args[0];
    397
    398	return 0;
    399}
    400
    401static int brcm_avs_set_pstate(struct private_data *priv, unsigned int pstate)
    402{
    403	u32 args[AVS_MAX_CMD_ARGS];
    404
    405	args[0] = pstate;
    406
    407	return __issue_avs_command(priv, AVS_CMD_SET_PSTATE, 1, 0, args);
    408
    409}
    410
    411static u32 brcm_avs_get_voltage(void __iomem *base)
    412{
    413	return readl(base + AVS_MBOX_VOLTAGE1);
    414}
    415
    416static u32 brcm_avs_get_frequency(void __iomem *base)
    417{
    418	return readl(base + AVS_MBOX_FREQUENCY) * 1000;	/* in kHz */
    419}
    420
    421/*
    422 * We determine which frequencies are supported by cycling through all P-states
    423 * and reading back what frequency we are running at for each P-state.
    424 */
    425static struct cpufreq_frequency_table *
    426brcm_avs_get_freq_table(struct device *dev, struct private_data *priv)
    427{
    428	struct cpufreq_frequency_table *table;
    429	unsigned int pstate;
    430	int i, ret;
    431
    432	/* Remember P-state for later */
    433	ret = brcm_avs_get_pstate(priv, &pstate);
    434	if (ret)
    435		return ERR_PTR(ret);
    436
    437	table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table),
    438			     GFP_KERNEL);
    439	if (!table)
    440		return ERR_PTR(-ENOMEM);
    441
    442	for (i = AVS_PSTATE_P0; i <= AVS_PSTATE_MAX; i++) {
    443		ret = brcm_avs_set_pstate(priv, i);
    444		if (ret)
    445			return ERR_PTR(ret);
    446		table[i].frequency = brcm_avs_get_frequency(priv->base);
    447		table[i].driver_data = i;
    448	}
    449	table[i].frequency = CPUFREQ_TABLE_END;
    450
    451	/* Restore P-state */
    452	ret = brcm_avs_set_pstate(priv, pstate);
    453	if (ret)
    454		return ERR_PTR(ret);
    455
    456	return table;
    457}
    458
    459/*
    460 * To ensure the right firmware is running we need to
    461 *    - check the MAGIC matches what we expect
    462 *    - brcm_avs_get_pmap() doesn't return -ENOTSUPP or -EINVAL
    463 * We need to set up our interrupt handling before calling brcm_avs_get_pmap()!
    464 */
    465static bool brcm_avs_is_firmware_loaded(struct private_data *priv)
    466{
    467	u32 magic;
    468	int rc;
    469
    470	rc = brcm_avs_get_pmap(priv, NULL);
    471	magic = readl(priv->base + AVS_MBOX_MAGIC);
    472
    473	return (magic == AVS_FIRMWARE_MAGIC) && ((rc != -ENOTSUPP) ||
    474		(rc != -EINVAL));
    475}
    476
    477static unsigned int brcm_avs_cpufreq_get(unsigned int cpu)
    478{
    479	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
    480	struct private_data *priv = policy->driver_data;
    481
    482	cpufreq_cpu_put(policy);
    483
    484	return brcm_avs_get_frequency(priv->base);
    485}
    486
    487static int brcm_avs_target_index(struct cpufreq_policy *policy,
    488				 unsigned int index)
    489{
    490	return brcm_avs_set_pstate(policy->driver_data,
    491				  policy->freq_table[index].driver_data);
    492}
    493
    494static int brcm_avs_suspend(struct cpufreq_policy *policy)
    495{
    496	struct private_data *priv = policy->driver_data;
    497	int ret;
    498
    499	ret = brcm_avs_get_pmap(priv, &priv->pmap);
    500	if (ret)
    501		return ret;
    502
    503	/*
    504	 * We can't use the P-state returned by brcm_avs_get_pmap(), since
    505	 * that's the initial P-state from when the P-map was downloaded to the
    506	 * AVS co-processor, not necessarily the P-state we are running at now.
    507	 * So, we get the current P-state explicitly.
    508	 */
    509	ret = brcm_avs_get_pstate(priv, &priv->pmap.state);
    510	if (ret)
    511		return ret;
    512
    513	/* This is best effort. Nothing to do if it fails. */
    514	(void)__issue_avs_command(priv, AVS_CMD_S2_ENTER, 0, 0, NULL);
    515
    516	return 0;
    517}
    518
    519static int brcm_avs_resume(struct cpufreq_policy *policy)
    520{
    521	struct private_data *priv = policy->driver_data;
    522	int ret;
    523
    524	/* This is best effort. Nothing to do if it fails. */
    525	(void)__issue_avs_command(priv, AVS_CMD_S2_EXIT, 0, 0, NULL);
    526
    527	ret = brcm_avs_set_pmap(priv, &priv->pmap);
    528	if (ret == -EEXIST) {
    529		struct platform_device *pdev  = cpufreq_get_driver_data();
    530		struct device *dev = &pdev->dev;
    531
    532		dev_warn(dev, "PMAP was already set\n");
    533		ret = 0;
    534	}
    535
    536	return ret;
    537}
    538
    539/*
    540 * All initialization code that we only want to execute once goes here. Setup
    541 * code that can be re-tried on every core (if it failed before) can go into
    542 * brcm_avs_cpufreq_init().
    543 */
    544static int brcm_avs_prepare_init(struct platform_device *pdev)
    545{
    546	struct private_data *priv;
    547	struct device *dev;
    548	int ret;
    549
    550	dev = &pdev->dev;
    551	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    552	if (!priv)
    553		return -ENOMEM;
    554
    555	priv->dev = dev;
    556	sema_init(&priv->sem, 1);
    557	init_completion(&priv->done);
    558	platform_set_drvdata(pdev, priv);
    559
    560	priv->base = __map_region(BRCM_AVS_CPU_DATA);
    561	if (!priv->base) {
    562		dev_err(dev, "Couldn't find property %s in device tree.\n",
    563			BRCM_AVS_CPU_DATA);
    564		return -ENOENT;
    565	}
    566
    567	priv->avs_intr_base = __map_region(BRCM_AVS_CPU_INTR);
    568	if (!priv->avs_intr_base) {
    569		dev_err(dev, "Couldn't find property %s in device tree.\n",
    570			BRCM_AVS_CPU_INTR);
    571		ret = -ENOENT;
    572		goto unmap_base;
    573	}
    574
    575	priv->host_irq = platform_get_irq_byname(pdev, BRCM_AVS_HOST_INTR);
    576
    577	ret = devm_request_irq(dev, priv->host_irq, irq_handler,
    578			       IRQF_TRIGGER_RISING,
    579			       BRCM_AVS_HOST_INTR, priv);
    580	if (ret && priv->host_irq >= 0) {
    581		dev_err(dev, "IRQ request failed: %s (%d) -- %d\n",
    582			BRCM_AVS_HOST_INTR, priv->host_irq, ret);
    583		goto unmap_intr_base;
    584	}
    585
    586	if (brcm_avs_is_firmware_loaded(priv))
    587		return 0;
    588
    589	dev_err(dev, "AVS firmware is not loaded or doesn't support DVFS\n");
    590	ret = -ENODEV;
    591
    592unmap_intr_base:
    593	iounmap(priv->avs_intr_base);
    594unmap_base:
    595	iounmap(priv->base);
    596
    597	return ret;
    598}
    599
    600static void brcm_avs_prepare_uninit(struct platform_device *pdev)
    601{
    602	struct private_data *priv;
    603
    604	priv = platform_get_drvdata(pdev);
    605
    606	iounmap(priv->avs_intr_base);
    607	iounmap(priv->base);
    608}
    609
    610static int brcm_avs_cpufreq_init(struct cpufreq_policy *policy)
    611{
    612	struct cpufreq_frequency_table *freq_table;
    613	struct platform_device *pdev;
    614	struct private_data *priv;
    615	struct device *dev;
    616	int ret;
    617
    618	pdev = cpufreq_get_driver_data();
    619	priv = platform_get_drvdata(pdev);
    620	policy->driver_data = priv;
    621	dev = &pdev->dev;
    622
    623	freq_table = brcm_avs_get_freq_table(dev, priv);
    624	if (IS_ERR(freq_table)) {
    625		ret = PTR_ERR(freq_table);
    626		dev_err(dev, "Couldn't determine frequency table (%d).\n", ret);
    627		return ret;
    628	}
    629
    630	policy->freq_table = freq_table;
    631
    632	/* All cores share the same clock and thus the same policy. */
    633	cpumask_setall(policy->cpus);
    634
    635	ret = __issue_avs_command(priv, AVS_CMD_ENABLE, 0, 0, NULL);
    636	if (!ret) {
    637		unsigned int pstate;
    638
    639		ret = brcm_avs_get_pstate(priv, &pstate);
    640		if (!ret) {
    641			policy->cur = freq_table[pstate].frequency;
    642			dev_info(dev, "registered\n");
    643			return 0;
    644		}
    645	}
    646
    647	dev_err(dev, "couldn't initialize driver (%d)\n", ret);
    648
    649	return ret;
    650}
    651
    652static ssize_t show_brcm_avs_pstate(struct cpufreq_policy *policy, char *buf)
    653{
    654	struct private_data *priv = policy->driver_data;
    655	unsigned int pstate;
    656
    657	if (brcm_avs_get_pstate(priv, &pstate))
    658		return sprintf(buf, "<unknown>\n");
    659
    660	return sprintf(buf, "%u\n", pstate);
    661}
    662
    663static ssize_t show_brcm_avs_mode(struct cpufreq_policy *policy, char *buf)
    664{
    665	struct private_data *priv = policy->driver_data;
    666	struct pmap pmap;
    667
    668	if (brcm_avs_get_pmap(priv, &pmap))
    669		return sprintf(buf, "<unknown>\n");
    670
    671	return sprintf(buf, "%s %u\n", brcm_avs_mode_to_string(pmap.mode),
    672		pmap.mode);
    673}
    674
    675static ssize_t show_brcm_avs_pmap(struct cpufreq_policy *policy, char *buf)
    676{
    677	unsigned int mdiv_p0, mdiv_p1, mdiv_p2, mdiv_p3, mdiv_p4;
    678	struct private_data *priv = policy->driver_data;
    679	unsigned int ndiv, pdiv;
    680	struct pmap pmap;
    681
    682	if (brcm_avs_get_pmap(priv, &pmap))
    683		return sprintf(buf, "<unknown>\n");
    684
    685	brcm_avs_parse_p1(pmap.p1, &mdiv_p0, &pdiv, &ndiv);
    686	brcm_avs_parse_p2(pmap.p2, &mdiv_p1, &mdiv_p2, &mdiv_p3, &mdiv_p4);
    687
    688	return sprintf(buf, "0x%08x 0x%08x %u %u %u %u %u %u %u %u %u\n",
    689		pmap.p1, pmap.p2, ndiv, pdiv, mdiv_p0, mdiv_p1, mdiv_p2,
    690		mdiv_p3, mdiv_p4, pmap.mode, pmap.state);
    691}
    692
    693static ssize_t show_brcm_avs_voltage(struct cpufreq_policy *policy, char *buf)
    694{
    695	struct private_data *priv = policy->driver_data;
    696
    697	return sprintf(buf, "0x%08x\n", brcm_avs_get_voltage(priv->base));
    698}
    699
    700static ssize_t show_brcm_avs_frequency(struct cpufreq_policy *policy, char *buf)
    701{
    702	struct private_data *priv = policy->driver_data;
    703
    704	return sprintf(buf, "0x%08x\n", brcm_avs_get_frequency(priv->base));
    705}
    706
    707cpufreq_freq_attr_ro(brcm_avs_pstate);
    708cpufreq_freq_attr_ro(brcm_avs_mode);
    709cpufreq_freq_attr_ro(brcm_avs_pmap);
    710cpufreq_freq_attr_ro(brcm_avs_voltage);
    711cpufreq_freq_attr_ro(brcm_avs_frequency);
    712
    713static struct freq_attr *brcm_avs_cpufreq_attr[] = {
    714	&cpufreq_freq_attr_scaling_available_freqs,
    715	&brcm_avs_pstate,
    716	&brcm_avs_mode,
    717	&brcm_avs_pmap,
    718	&brcm_avs_voltage,
    719	&brcm_avs_frequency,
    720	NULL
    721};
    722
    723static struct cpufreq_driver brcm_avs_driver = {
    724	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK,
    725	.verify		= cpufreq_generic_frequency_table_verify,
    726	.target_index	= brcm_avs_target_index,
    727	.get		= brcm_avs_cpufreq_get,
    728	.suspend	= brcm_avs_suspend,
    729	.resume		= brcm_avs_resume,
    730	.init		= brcm_avs_cpufreq_init,
    731	.attr		= brcm_avs_cpufreq_attr,
    732	.name		= BRCM_AVS_CPUFREQ_PREFIX,
    733};
    734
    735static int brcm_avs_cpufreq_probe(struct platform_device *pdev)
    736{
    737	int ret;
    738
    739	ret = brcm_avs_prepare_init(pdev);
    740	if (ret)
    741		return ret;
    742
    743	brcm_avs_driver.driver_data = pdev;
    744
    745	ret = cpufreq_register_driver(&brcm_avs_driver);
    746	if (ret)
    747		brcm_avs_prepare_uninit(pdev);
    748
    749	return ret;
    750}
    751
    752static int brcm_avs_cpufreq_remove(struct platform_device *pdev)
    753{
    754	int ret;
    755
    756	ret = cpufreq_unregister_driver(&brcm_avs_driver);
    757	WARN_ON(ret);
    758
    759	brcm_avs_prepare_uninit(pdev);
    760
    761	return 0;
    762}
    763
    764static const struct of_device_id brcm_avs_cpufreq_match[] = {
    765	{ .compatible = BRCM_AVS_CPU_DATA },
    766	{ }
    767};
    768MODULE_DEVICE_TABLE(of, brcm_avs_cpufreq_match);
    769
    770static struct platform_driver brcm_avs_cpufreq_platdrv = {
    771	.driver = {
    772		.name	= BRCM_AVS_CPUFREQ_NAME,
    773		.of_match_table = brcm_avs_cpufreq_match,
    774	},
    775	.probe		= brcm_avs_cpufreq_probe,
    776	.remove		= brcm_avs_cpufreq_remove,
    777};
    778module_platform_driver(brcm_avs_cpufreq_platdrv);
    779
    780MODULE_AUTHOR("Markus Mayer <mmayer@broadcom.com>");
    781MODULE_DESCRIPTION("CPUfreq driver for Broadcom STB AVS");
    782MODULE_LICENSE("GPL");