Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * CPU frequency scaling for Broadcom SoCs with AVS firmware that
0003  * supports DVS or DVFS
0004  *
0005  * Copyright (c) 2016 Broadcom
0006  *
0007  * This program is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU General Public License as
0009  * published by the Free Software Foundation version 2.
0010  *
0011  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
0012  * kind, whether express or implied; without even the implied warranty
0013  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  */
0016 
0017 /*
0018  * "AVS" is the name of a firmware developed at Broadcom. It derives
0019  * its name from the technique called "Adaptive Voltage Scaling".
0020  * Adaptive voltage scaling was the original purpose of this firmware.
0021  * The AVS firmware still supports "AVS mode", where all it does is
0022  * adaptive voltage scaling. However, on some newer Broadcom SoCs, the
0023  * AVS Firmware, despite its unchanged name, also supports DFS mode and
0024  * DVFS mode.
0025  *
0026  * In the context of this document and the related driver, "AVS" by
0027  * itself always means the Broadcom firmware and never refers to the
0028  * technique called "Adaptive Voltage Scaling".
0029  *
0030  * The Broadcom STB AVS CPUfreq driver provides voltage and frequency
0031  * scaling on Broadcom SoCs using AVS firmware with support for DFS and
0032  * DVFS. The AVS firmware is running on its own co-processor. The
0033  * driver supports both uniprocessor (UP) and symmetric multiprocessor
0034  * (SMP) systems which share clock and voltage across all CPUs.
0035  *
0036  * Actual voltage and frequency scaling is done solely by the AVS
0037  * firmware. This driver does not change frequency or voltage itself.
0038  * It provides a standard CPUfreq interface to the rest of the kernel
0039  * and to userland. It interfaces with the AVS firmware to effect the
0040  * requested changes and to report back the current system status in a
0041  * way that is expected by existing tools.
0042  */
0043 
0044 #include <linux/cpufreq.h>
0045 #include <linux/delay.h>
0046 #include <linux/interrupt.h>
0047 #include <linux/io.h>
0048 #include <linux/module.h>
0049 #include <linux/of_address.h>
0050 #include <linux/platform_device.h>
0051 #include <linux/semaphore.h>
0052 
0053 /* Max number of arguments AVS calls take */
0054 #define AVS_MAX_CMD_ARGS    4
0055 /*
0056  * This macro is used to generate AVS parameter register offsets. For
0057  * x >= AVS_MAX_CMD_ARGS, it returns 0 to protect against accidental memory
0058  * access outside of the parameter range. (Offset 0 is the first parameter.)
0059  */
0060 #define AVS_PARAM_MULT(x)   ((x) < AVS_MAX_CMD_ARGS ? (x) : 0)
0061 
0062 /* AVS Mailbox Register offsets */
0063 #define AVS_MBOX_COMMAND    0x00
0064 #define AVS_MBOX_STATUS     0x04
0065 #define AVS_MBOX_VOLTAGE0   0x08
0066 #define AVS_MBOX_TEMP0      0x0c
0067 #define AVS_MBOX_PV0        0x10
0068 #define AVS_MBOX_MV0        0x14
0069 #define AVS_MBOX_PARAM(x)   (0x18 + AVS_PARAM_MULT(x) * sizeof(u32))
0070 #define AVS_MBOX_REVISION   0x28
0071 #define AVS_MBOX_PSTATE     0x2c
0072 #define AVS_MBOX_HEARTBEAT  0x30
0073 #define AVS_MBOX_MAGIC      0x34
0074 #define AVS_MBOX_SIGMA_HVT  0x38
0075 #define AVS_MBOX_SIGMA_SVT  0x3c
0076 #define AVS_MBOX_VOLTAGE1   0x40
0077 #define AVS_MBOX_TEMP1      0x44
0078 #define AVS_MBOX_PV1        0x48
0079 #define AVS_MBOX_MV1        0x4c
0080 #define AVS_MBOX_FREQUENCY  0x50
0081 
0082 /* AVS Commands */
0083 #define AVS_CMD_AVAILABLE   0x00
0084 #define AVS_CMD_DISABLE     0x10
0085 #define AVS_CMD_ENABLE      0x11
0086 #define AVS_CMD_S2_ENTER    0x12
0087 #define AVS_CMD_S2_EXIT     0x13
0088 #define AVS_CMD_BBM_ENTER   0x14
0089 #define AVS_CMD_BBM_EXIT    0x15
0090 #define AVS_CMD_S3_ENTER    0x16
0091 #define AVS_CMD_S3_EXIT     0x17
0092 #define AVS_CMD_BALANCE     0x18
0093 /* PMAP and P-STATE commands */
0094 #define AVS_CMD_GET_PMAP    0x30
0095 #define AVS_CMD_SET_PMAP    0x31
0096 #define AVS_CMD_GET_PSTATE  0x40
0097 #define AVS_CMD_SET_PSTATE  0x41
0098 
0099 /* Different modes AVS supports (for GET_PMAP/SET_PMAP) */
0100 #define AVS_MODE_AVS        0x0
0101 #define AVS_MODE_DFS        0x1
0102 #define AVS_MODE_DVS        0x2
0103 #define AVS_MODE_DVFS       0x3
0104 
0105 /*
0106  * PMAP parameter p1
0107  * unused:31-24, mdiv_p0:23-16, unused:15-14, pdiv:13-10 , ndiv_int:9-0
0108  */
0109 #define NDIV_INT_SHIFT      0
0110 #define NDIV_INT_MASK       0x3ff
0111 #define PDIV_SHIFT      10
0112 #define PDIV_MASK       0xf
0113 #define MDIV_P0_SHIFT       16
0114 #define MDIV_P0_MASK        0xff
0115 /*
0116  * PMAP parameter p2
0117  * mdiv_p4:31-24, mdiv_p3:23-16, mdiv_p2:15:8, mdiv_p1:7:0
0118  */
0119 #define MDIV_P1_SHIFT       0
0120 #define MDIV_P1_MASK        0xff
0121 #define MDIV_P2_SHIFT       8
0122 #define MDIV_P2_MASK        0xff
0123 #define MDIV_P3_SHIFT       16
0124 #define MDIV_P3_MASK        0xff
0125 #define MDIV_P4_SHIFT       24
0126 #define MDIV_P4_MASK        0xff
0127 
0128 /* Different P-STATES AVS supports (for GET_PSTATE/SET_PSTATE) */
0129 #define AVS_PSTATE_P0       0x0
0130 #define AVS_PSTATE_P1       0x1
0131 #define AVS_PSTATE_P2       0x2
0132 #define AVS_PSTATE_P3       0x3
0133 #define AVS_PSTATE_P4       0x4
0134 #define AVS_PSTATE_MAX      AVS_PSTATE_P4
0135 
0136 /* CPU L2 Interrupt Controller Registers */
0137 #define AVS_CPU_L2_SET0     0x04
0138 #define AVS_CPU_L2_INT_MASK BIT(31)
0139 
0140 /* AVS Command Status Values */
0141 #define AVS_STATUS_CLEAR    0x00
0142 /* Command/notification accepted */
0143 #define AVS_STATUS_SUCCESS  0xf0
0144 /* Command/notification rejected */
0145 #define AVS_STATUS_FAILURE  0xff
0146 /* Invalid command/notification (unknown) */
0147 #define AVS_STATUS_INVALID  0xf1
0148 /* Non-AVS modes are not supported */
0149 #define AVS_STATUS_NO_SUPP  0xf2
0150 /* Cannot set P-State until P-Map supplied */
0151 #define AVS_STATUS_NO_MAP   0xf3
0152 /* Cannot change P-Map after initial P-Map set */
0153 #define AVS_STATUS_MAP_SET  0xf4
0154 /* Max AVS status; higher numbers are used for debugging */
0155 #define AVS_STATUS_MAX      0xff
0156 
0157 /* Other AVS related constants */
0158 #define AVS_LOOP_LIMIT      10000
0159 #define AVS_TIMEOUT     300 /* in ms; expected completion is < 10ms */
0160 #define AVS_FIRMWARE_MAGIC  0xa11600d1
0161 
0162 #define BRCM_AVS_CPUFREQ_PREFIX "brcmstb-avs"
0163 #define BRCM_AVS_CPUFREQ_NAME   BRCM_AVS_CPUFREQ_PREFIX "-cpufreq"
0164 #define BRCM_AVS_CPU_DATA   "brcm,avs-cpu-data-mem"
0165 #define BRCM_AVS_CPU_INTR   "brcm,avs-cpu-l2-intr"
0166 #define BRCM_AVS_HOST_INTR  "sw_intr"
0167 
0168 struct pmap {
0169     unsigned int mode;
0170     unsigned int p1;
0171     unsigned int p2;
0172     unsigned int state;
0173 };
0174 
0175 struct private_data {
0176     void __iomem *base;
0177     void __iomem *avs_intr_base;
0178     struct device *dev;
0179     struct completion done;
0180     struct semaphore sem;
0181     struct pmap pmap;
0182     int host_irq;
0183 };
0184 
0185 static void __iomem *__map_region(const char *name)
0186 {
0187     struct device_node *np;
0188     void __iomem *ptr;
0189 
0190     np = of_find_compatible_node(NULL, NULL, name);
0191     if (!np)
0192         return NULL;
0193 
0194     ptr = of_iomap(np, 0);
0195     of_node_put(np);
0196 
0197     return ptr;
0198 }
0199 
0200 static unsigned long wait_for_avs_command(struct private_data *priv,
0201                       unsigned long timeout)
0202 {
0203     unsigned long time_left = 0;
0204     u32 val;
0205 
0206     /* Event driven, wait for the command interrupt */
0207     if (priv->host_irq >= 0)
0208         return wait_for_completion_timeout(&priv->done,
0209                            msecs_to_jiffies(timeout));
0210 
0211     /* Polling for command completion */
0212     do {
0213         time_left = timeout;
0214         val = readl(priv->base + AVS_MBOX_STATUS);
0215         if (val)
0216             break;
0217 
0218         usleep_range(1000, 2000);
0219     } while (--timeout);
0220 
0221     return time_left;
0222 }
0223 
0224 static int __issue_avs_command(struct private_data *priv, unsigned int cmd,
0225                    unsigned int num_in, unsigned int num_out,
0226                    u32 args[])
0227 {
0228     void __iomem *base = priv->base;
0229     unsigned long time_left;
0230     unsigned int i;
0231     int ret;
0232     u32 val;
0233 
0234     ret = down_interruptible(&priv->sem);
0235     if (ret)
0236         return ret;
0237 
0238     /*
0239      * Make sure no other command is currently running: cmd is 0 if AVS
0240      * co-processor is idle. Due to the guard above, we should almost never
0241      * have to wait here.
0242      */
0243     for (i = 0, val = 1; val != 0 && i < AVS_LOOP_LIMIT; i++)
0244         val = readl(base + AVS_MBOX_COMMAND);
0245 
0246     /* Give the caller a chance to retry if AVS is busy. */
0247     if (i == AVS_LOOP_LIMIT) {
0248         ret = -EAGAIN;
0249         goto out;
0250     }
0251 
0252     /* Clear status before we begin. */
0253     writel(AVS_STATUS_CLEAR, base + AVS_MBOX_STATUS);
0254 
0255     /* Provide input parameters */
0256     for (i = 0; i < num_in; i++)
0257         writel(args[i], base + AVS_MBOX_PARAM(i));
0258 
0259     /* Protect from spurious interrupts. */
0260     reinit_completion(&priv->done);
0261 
0262     /* Now issue the command & tell firmware to wake up to process it. */
0263     writel(cmd, base + AVS_MBOX_COMMAND);
0264     writel(AVS_CPU_L2_INT_MASK, priv->avs_intr_base + AVS_CPU_L2_SET0);
0265 
0266     /* Wait for AVS co-processor to finish processing the command. */
0267     time_left = wait_for_avs_command(priv, AVS_TIMEOUT);
0268 
0269     /*
0270      * If the AVS status is not in the expected range, it means AVS didn't
0271      * complete our command in time, and we return an error. Also, if there
0272      * is no "time left", we timed out waiting for the interrupt.
0273      */
0274     val = readl(base + AVS_MBOX_STATUS);
0275     if (time_left == 0 || val == 0 || val > AVS_STATUS_MAX) {
0276         dev_err(priv->dev, "AVS command %#x didn't complete in time\n",
0277             cmd);
0278         dev_err(priv->dev, "    Time left: %u ms, AVS status: %#x\n",
0279             jiffies_to_msecs(time_left), val);
0280         ret = -ETIMEDOUT;
0281         goto out;
0282     }
0283 
0284     /* Process returned values */
0285     for (i = 0; i < num_out; i++)
0286         args[i] = readl(base + AVS_MBOX_PARAM(i));
0287 
0288     /* Clear status to tell AVS co-processor we are done. */
0289     writel(AVS_STATUS_CLEAR, base + AVS_MBOX_STATUS);
0290 
0291     /* Convert firmware errors to errno's as much as possible. */
0292     switch (val) {
0293     case AVS_STATUS_INVALID:
0294         ret = -EINVAL;
0295         break;
0296     case AVS_STATUS_NO_SUPP:
0297         ret = -ENOTSUPP;
0298         break;
0299     case AVS_STATUS_NO_MAP:
0300         ret = -ENOENT;
0301         break;
0302     case AVS_STATUS_MAP_SET:
0303         ret = -EEXIST;
0304         break;
0305     case AVS_STATUS_FAILURE:
0306         ret = -EIO;
0307         break;
0308     }
0309 
0310 out:
0311     up(&priv->sem);
0312 
0313     return ret;
0314 }
0315 
0316 static irqreturn_t irq_handler(int irq, void *data)
0317 {
0318     struct private_data *priv = data;
0319 
0320     /* AVS command completed execution. Wake up __issue_avs_command(). */
0321     complete(&priv->done);
0322 
0323     return IRQ_HANDLED;
0324 }
0325 
0326 static char *brcm_avs_mode_to_string(unsigned int mode)
0327 {
0328     switch (mode) {
0329     case AVS_MODE_AVS:
0330         return "AVS";
0331     case AVS_MODE_DFS:
0332         return "DFS";
0333     case AVS_MODE_DVS:
0334         return "DVS";
0335     case AVS_MODE_DVFS:
0336         return "DVFS";
0337     }
0338     return NULL;
0339 }
0340 
0341 static void brcm_avs_parse_p1(u32 p1, unsigned int *mdiv_p0, unsigned int *pdiv,
0342                   unsigned int *ndiv)
0343 {
0344     *mdiv_p0 = (p1 >> MDIV_P0_SHIFT) & MDIV_P0_MASK;
0345     *pdiv = (p1 >> PDIV_SHIFT) & PDIV_MASK;
0346     *ndiv = (p1 >> NDIV_INT_SHIFT) & NDIV_INT_MASK;
0347 }
0348 
0349 static void brcm_avs_parse_p2(u32 p2, unsigned int *mdiv_p1,
0350                   unsigned int *mdiv_p2, unsigned int *mdiv_p3,
0351                   unsigned int *mdiv_p4)
0352 {
0353     *mdiv_p4 = (p2 >> MDIV_P4_SHIFT) & MDIV_P4_MASK;
0354     *mdiv_p3 = (p2 >> MDIV_P3_SHIFT) & MDIV_P3_MASK;
0355     *mdiv_p2 = (p2 >> MDIV_P2_SHIFT) & MDIV_P2_MASK;
0356     *mdiv_p1 = (p2 >> MDIV_P1_SHIFT) & MDIV_P1_MASK;
0357 }
0358 
0359 static int brcm_avs_get_pmap(struct private_data *priv, struct pmap *pmap)
0360 {
0361     u32 args[AVS_MAX_CMD_ARGS];
0362     int ret;
0363 
0364     ret = __issue_avs_command(priv, AVS_CMD_GET_PMAP, 0, 4, args);
0365     if (ret || !pmap)
0366         return ret;
0367 
0368     pmap->mode = args[0];
0369     pmap->p1 = args[1];
0370     pmap->p2 = args[2];
0371     pmap->state = args[3];
0372 
0373     return 0;
0374 }
0375 
0376 static int brcm_avs_set_pmap(struct private_data *priv, struct pmap *pmap)
0377 {
0378     u32 args[AVS_MAX_CMD_ARGS];
0379 
0380     args[0] = pmap->mode;
0381     args[1] = pmap->p1;
0382     args[2] = pmap->p2;
0383     args[3] = pmap->state;
0384 
0385     return __issue_avs_command(priv, AVS_CMD_SET_PMAP, 4, 0, args);
0386 }
0387 
0388 static int brcm_avs_get_pstate(struct private_data *priv, unsigned int *pstate)
0389 {
0390     u32 args[AVS_MAX_CMD_ARGS];
0391     int ret;
0392 
0393     ret = __issue_avs_command(priv, AVS_CMD_GET_PSTATE, 0, 1, args);
0394     if (ret)
0395         return ret;
0396     *pstate = args[0];
0397 
0398     return 0;
0399 }
0400 
0401 static int brcm_avs_set_pstate(struct private_data *priv, unsigned int pstate)
0402 {
0403     u32 args[AVS_MAX_CMD_ARGS];
0404 
0405     args[0] = pstate;
0406 
0407     return __issue_avs_command(priv, AVS_CMD_SET_PSTATE, 1, 0, args);
0408 
0409 }
0410 
0411 static u32 brcm_avs_get_voltage(void __iomem *base)
0412 {
0413     return readl(base + AVS_MBOX_VOLTAGE1);
0414 }
0415 
0416 static u32 brcm_avs_get_frequency(void __iomem *base)
0417 {
0418     return readl(base + AVS_MBOX_FREQUENCY) * 1000; /* in kHz */
0419 }
0420 
0421 /*
0422  * We determine which frequencies are supported by cycling through all P-states
0423  * and reading back what frequency we are running at for each P-state.
0424  */
0425 static struct cpufreq_frequency_table *
0426 brcm_avs_get_freq_table(struct device *dev, struct private_data *priv)
0427 {
0428     struct cpufreq_frequency_table *table;
0429     unsigned int pstate;
0430     int i, ret;
0431 
0432     /* Remember P-state for later */
0433     ret = brcm_avs_get_pstate(priv, &pstate);
0434     if (ret)
0435         return ERR_PTR(ret);
0436 
0437     table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table),
0438                  GFP_KERNEL);
0439     if (!table)
0440         return ERR_PTR(-ENOMEM);
0441 
0442     for (i = AVS_PSTATE_P0; i <= AVS_PSTATE_MAX; i++) {
0443         ret = brcm_avs_set_pstate(priv, i);
0444         if (ret)
0445             return ERR_PTR(ret);
0446         table[i].frequency = brcm_avs_get_frequency(priv->base);
0447         table[i].driver_data = i;
0448     }
0449     table[i].frequency = CPUFREQ_TABLE_END;
0450 
0451     /* Restore P-state */
0452     ret = brcm_avs_set_pstate(priv, pstate);
0453     if (ret)
0454         return ERR_PTR(ret);
0455 
0456     return table;
0457 }
0458 
0459 /*
0460  * To ensure the right firmware is running we need to
0461  *    - check the MAGIC matches what we expect
0462  *    - brcm_avs_get_pmap() doesn't return -ENOTSUPP or -EINVAL
0463  * We need to set up our interrupt handling before calling brcm_avs_get_pmap()!
0464  */
0465 static bool brcm_avs_is_firmware_loaded(struct private_data *priv)
0466 {
0467     u32 magic;
0468     int rc;
0469 
0470     rc = brcm_avs_get_pmap(priv, NULL);
0471     magic = readl(priv->base + AVS_MBOX_MAGIC);
0472 
0473     return (magic == AVS_FIRMWARE_MAGIC) && ((rc != -ENOTSUPP) ||
0474         (rc != -EINVAL));
0475 }
0476 
0477 static unsigned int brcm_avs_cpufreq_get(unsigned int cpu)
0478 {
0479     struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
0480     struct private_data *priv = policy->driver_data;
0481 
0482     cpufreq_cpu_put(policy);
0483 
0484     return brcm_avs_get_frequency(priv->base);
0485 }
0486 
0487 static int brcm_avs_target_index(struct cpufreq_policy *policy,
0488                  unsigned int index)
0489 {
0490     return brcm_avs_set_pstate(policy->driver_data,
0491                   policy->freq_table[index].driver_data);
0492 }
0493 
0494 static int brcm_avs_suspend(struct cpufreq_policy *policy)
0495 {
0496     struct private_data *priv = policy->driver_data;
0497     int ret;
0498 
0499     ret = brcm_avs_get_pmap(priv, &priv->pmap);
0500     if (ret)
0501         return ret;
0502 
0503     /*
0504      * We can't use the P-state returned by brcm_avs_get_pmap(), since
0505      * that's the initial P-state from when the P-map was downloaded to the
0506      * AVS co-processor, not necessarily the P-state we are running at now.
0507      * So, we get the current P-state explicitly.
0508      */
0509     ret = brcm_avs_get_pstate(priv, &priv->pmap.state);
0510     if (ret)
0511         return ret;
0512 
0513     /* This is best effort. Nothing to do if it fails. */
0514     (void)__issue_avs_command(priv, AVS_CMD_S2_ENTER, 0, 0, NULL);
0515 
0516     return 0;
0517 }
0518 
0519 static int brcm_avs_resume(struct cpufreq_policy *policy)
0520 {
0521     struct private_data *priv = policy->driver_data;
0522     int ret;
0523 
0524     /* This is best effort. Nothing to do if it fails. */
0525     (void)__issue_avs_command(priv, AVS_CMD_S2_EXIT, 0, 0, NULL);
0526 
0527     ret = brcm_avs_set_pmap(priv, &priv->pmap);
0528     if (ret == -EEXIST) {
0529         struct platform_device *pdev  = cpufreq_get_driver_data();
0530         struct device *dev = &pdev->dev;
0531 
0532         dev_warn(dev, "PMAP was already set\n");
0533         ret = 0;
0534     }
0535 
0536     return ret;
0537 }
0538 
0539 /*
0540  * All initialization code that we only want to execute once goes here. Setup
0541  * code that can be re-tried on every core (if it failed before) can go into
0542  * brcm_avs_cpufreq_init().
0543  */
0544 static int brcm_avs_prepare_init(struct platform_device *pdev)
0545 {
0546     struct private_data *priv;
0547     struct device *dev;
0548     int ret;
0549 
0550     dev = &pdev->dev;
0551     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0552     if (!priv)
0553         return -ENOMEM;
0554 
0555     priv->dev = dev;
0556     sema_init(&priv->sem, 1);
0557     init_completion(&priv->done);
0558     platform_set_drvdata(pdev, priv);
0559 
0560     priv->base = __map_region(BRCM_AVS_CPU_DATA);
0561     if (!priv->base) {
0562         dev_err(dev, "Couldn't find property %s in device tree.\n",
0563             BRCM_AVS_CPU_DATA);
0564         return -ENOENT;
0565     }
0566 
0567     priv->avs_intr_base = __map_region(BRCM_AVS_CPU_INTR);
0568     if (!priv->avs_intr_base) {
0569         dev_err(dev, "Couldn't find property %s in device tree.\n",
0570             BRCM_AVS_CPU_INTR);
0571         ret = -ENOENT;
0572         goto unmap_base;
0573     }
0574 
0575     priv->host_irq = platform_get_irq_byname(pdev, BRCM_AVS_HOST_INTR);
0576 
0577     ret = devm_request_irq(dev, priv->host_irq, irq_handler,
0578                    IRQF_TRIGGER_RISING,
0579                    BRCM_AVS_HOST_INTR, priv);
0580     if (ret && priv->host_irq >= 0) {
0581         dev_err(dev, "IRQ request failed: %s (%d) -- %d\n",
0582             BRCM_AVS_HOST_INTR, priv->host_irq, ret);
0583         goto unmap_intr_base;
0584     }
0585 
0586     if (brcm_avs_is_firmware_loaded(priv))
0587         return 0;
0588 
0589     dev_err(dev, "AVS firmware is not loaded or doesn't support DVFS\n");
0590     ret = -ENODEV;
0591 
0592 unmap_intr_base:
0593     iounmap(priv->avs_intr_base);
0594 unmap_base:
0595     iounmap(priv->base);
0596 
0597     return ret;
0598 }
0599 
0600 static void brcm_avs_prepare_uninit(struct platform_device *pdev)
0601 {
0602     struct private_data *priv;
0603 
0604     priv = platform_get_drvdata(pdev);
0605 
0606     iounmap(priv->avs_intr_base);
0607     iounmap(priv->base);
0608 }
0609 
0610 static int brcm_avs_cpufreq_init(struct cpufreq_policy *policy)
0611 {
0612     struct cpufreq_frequency_table *freq_table;
0613     struct platform_device *pdev;
0614     struct private_data *priv;
0615     struct device *dev;
0616     int ret;
0617 
0618     pdev = cpufreq_get_driver_data();
0619     priv = platform_get_drvdata(pdev);
0620     policy->driver_data = priv;
0621     dev = &pdev->dev;
0622 
0623     freq_table = brcm_avs_get_freq_table(dev, priv);
0624     if (IS_ERR(freq_table)) {
0625         ret = PTR_ERR(freq_table);
0626         dev_err(dev, "Couldn't determine frequency table (%d).\n", ret);
0627         return ret;
0628     }
0629 
0630     policy->freq_table = freq_table;
0631 
0632     /* All cores share the same clock and thus the same policy. */
0633     cpumask_setall(policy->cpus);
0634 
0635     ret = __issue_avs_command(priv, AVS_CMD_ENABLE, 0, 0, NULL);
0636     if (!ret) {
0637         unsigned int pstate;
0638 
0639         ret = brcm_avs_get_pstate(priv, &pstate);
0640         if (!ret) {
0641             policy->cur = freq_table[pstate].frequency;
0642             dev_info(dev, "registered\n");
0643             return 0;
0644         }
0645     }
0646 
0647     dev_err(dev, "couldn't initialize driver (%d)\n", ret);
0648 
0649     return ret;
0650 }
0651 
0652 static ssize_t show_brcm_avs_pstate(struct cpufreq_policy *policy, char *buf)
0653 {
0654     struct private_data *priv = policy->driver_data;
0655     unsigned int pstate;
0656 
0657     if (brcm_avs_get_pstate(priv, &pstate))
0658         return sprintf(buf, "<unknown>\n");
0659 
0660     return sprintf(buf, "%u\n", pstate);
0661 }
0662 
0663 static ssize_t show_brcm_avs_mode(struct cpufreq_policy *policy, char *buf)
0664 {
0665     struct private_data *priv = policy->driver_data;
0666     struct pmap pmap;
0667 
0668     if (brcm_avs_get_pmap(priv, &pmap))
0669         return sprintf(buf, "<unknown>\n");
0670 
0671     return sprintf(buf, "%s %u\n", brcm_avs_mode_to_string(pmap.mode),
0672         pmap.mode);
0673 }
0674 
0675 static ssize_t show_brcm_avs_pmap(struct cpufreq_policy *policy, char *buf)
0676 {
0677     unsigned int mdiv_p0, mdiv_p1, mdiv_p2, mdiv_p3, mdiv_p4;
0678     struct private_data *priv = policy->driver_data;
0679     unsigned int ndiv, pdiv;
0680     struct pmap pmap;
0681 
0682     if (brcm_avs_get_pmap(priv, &pmap))
0683         return sprintf(buf, "<unknown>\n");
0684 
0685     brcm_avs_parse_p1(pmap.p1, &mdiv_p0, &pdiv, &ndiv);
0686     brcm_avs_parse_p2(pmap.p2, &mdiv_p1, &mdiv_p2, &mdiv_p3, &mdiv_p4);
0687 
0688     return sprintf(buf, "0x%08x 0x%08x %u %u %u %u %u %u %u %u %u\n",
0689         pmap.p1, pmap.p2, ndiv, pdiv, mdiv_p0, mdiv_p1, mdiv_p2,
0690         mdiv_p3, mdiv_p4, pmap.mode, pmap.state);
0691 }
0692 
0693 static ssize_t show_brcm_avs_voltage(struct cpufreq_policy *policy, char *buf)
0694 {
0695     struct private_data *priv = policy->driver_data;
0696 
0697     return sprintf(buf, "0x%08x\n", brcm_avs_get_voltage(priv->base));
0698 }
0699 
0700 static ssize_t show_brcm_avs_frequency(struct cpufreq_policy *policy, char *buf)
0701 {
0702     struct private_data *priv = policy->driver_data;
0703 
0704     return sprintf(buf, "0x%08x\n", brcm_avs_get_frequency(priv->base));
0705 }
0706 
0707 cpufreq_freq_attr_ro(brcm_avs_pstate);
0708 cpufreq_freq_attr_ro(brcm_avs_mode);
0709 cpufreq_freq_attr_ro(brcm_avs_pmap);
0710 cpufreq_freq_attr_ro(brcm_avs_voltage);
0711 cpufreq_freq_attr_ro(brcm_avs_frequency);
0712 
0713 static struct freq_attr *brcm_avs_cpufreq_attr[] = {
0714     &cpufreq_freq_attr_scaling_available_freqs,
0715     &brcm_avs_pstate,
0716     &brcm_avs_mode,
0717     &brcm_avs_pmap,
0718     &brcm_avs_voltage,
0719     &brcm_avs_frequency,
0720     NULL
0721 };
0722 
0723 static struct cpufreq_driver brcm_avs_driver = {
0724     .flags      = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
0725     .verify     = cpufreq_generic_frequency_table_verify,
0726     .target_index   = brcm_avs_target_index,
0727     .get        = brcm_avs_cpufreq_get,
0728     .suspend    = brcm_avs_suspend,
0729     .resume     = brcm_avs_resume,
0730     .init       = brcm_avs_cpufreq_init,
0731     .attr       = brcm_avs_cpufreq_attr,
0732     .name       = BRCM_AVS_CPUFREQ_PREFIX,
0733 };
0734 
0735 static int brcm_avs_cpufreq_probe(struct platform_device *pdev)
0736 {
0737     int ret;
0738 
0739     ret = brcm_avs_prepare_init(pdev);
0740     if (ret)
0741         return ret;
0742 
0743     brcm_avs_driver.driver_data = pdev;
0744 
0745     ret = cpufreq_register_driver(&brcm_avs_driver);
0746     if (ret)
0747         brcm_avs_prepare_uninit(pdev);
0748 
0749     return ret;
0750 }
0751 
0752 static int brcm_avs_cpufreq_remove(struct platform_device *pdev)
0753 {
0754     int ret;
0755 
0756     ret = cpufreq_unregister_driver(&brcm_avs_driver);
0757     WARN_ON(ret);
0758 
0759     brcm_avs_prepare_uninit(pdev);
0760 
0761     return 0;
0762 }
0763 
0764 static const struct of_device_id brcm_avs_cpufreq_match[] = {
0765     { .compatible = BRCM_AVS_CPU_DATA },
0766     { }
0767 };
0768 MODULE_DEVICE_TABLE(of, brcm_avs_cpufreq_match);
0769 
0770 static struct platform_driver brcm_avs_cpufreq_platdrv = {
0771     .driver = {
0772         .name   = BRCM_AVS_CPUFREQ_NAME,
0773         .of_match_table = brcm_avs_cpufreq_match,
0774     },
0775     .probe      = brcm_avs_cpufreq_probe,
0776     .remove     = brcm_avs_cpufreq_remove,
0777 };
0778 module_platform_driver(brcm_avs_cpufreq_platdrv);
0779 
0780 MODULE_AUTHOR("Markus Mayer <mmayer@broadcom.com>");
0781 MODULE_DESCRIPTION("CPUfreq driver for Broadcom STB AVS");
0782 MODULE_LICENSE("GPL");