linux/drivers/devfreq/exynos-bus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Generic Exynos Bus frequency driver with DEVFREQ Framework
   4 *
   5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
   6 * Author : Chanwoo Choi <cw00.choi@samsung.com>
   7 *
   8 * This driver support Exynos Bus frequency feature by using
   9 * DEVFREQ framework and is based on drivers/devfreq/exynos/exynos4_bus.c.
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/devfreq.h>
  14#include <linux/devfreq-event.h>
  15#include <linux/device.h>
  16#include <linux/export.h>
  17#include <linux/module.h>
  18#include <linux/of_device.h>
  19#include <linux/pm_opp.h>
  20#include <linux/platform_device.h>
  21#include <linux/regulator/consumer.h>
  22#include <linux/slab.h>
  23
  24#define DEFAULT_SATURATION_RATIO        40
  25#define DEFAULT_VOLTAGE_TOLERANCE       2
  26
  27struct exynos_bus {
  28        struct device *dev;
  29
  30        struct devfreq *devfreq;
  31        struct devfreq_event_dev **edev;
  32        unsigned int edev_count;
  33        struct mutex lock;
  34
  35        unsigned long curr_freq;
  36
  37        struct regulator *regulator;
  38        struct clk *clk;
  39        unsigned int voltage_tolerance;
  40        unsigned int ratio;
  41};
  42
  43/*
  44 * Control the devfreq-event device to get the current state of bus
  45 */
  46#define exynos_bus_ops_edev(ops)                                \
  47static int exynos_bus_##ops(struct exynos_bus *bus)             \
  48{                                                               \
  49        int i, ret;                                             \
  50                                                                \
  51        for (i = 0; i < bus->edev_count; i++) {                 \
  52                if (!bus->edev[i])                              \
  53                        continue;                               \
  54                ret = devfreq_event_##ops(bus->edev[i]);        \
  55                if (ret < 0)                                    \
  56                        return ret;                             \
  57        }                                                       \
  58                                                                \
  59        return 0;                                               \
  60}
  61exynos_bus_ops_edev(enable_edev);
  62exynos_bus_ops_edev(disable_edev);
  63exynos_bus_ops_edev(set_event);
  64
  65static int exynos_bus_get_event(struct exynos_bus *bus,
  66                                struct devfreq_event_data *edata)
  67{
  68        struct devfreq_event_data event_data;
  69        unsigned long load_count = 0, total_count = 0;
  70        int i, ret = 0;
  71
  72        for (i = 0; i < bus->edev_count; i++) {
  73                if (!bus->edev[i])
  74                        continue;
  75
  76                ret = devfreq_event_get_event(bus->edev[i], &event_data);
  77                if (ret < 0)
  78                        return ret;
  79
  80                if (i == 0 || event_data.load_count > load_count) {
  81                        load_count = event_data.load_count;
  82                        total_count = event_data.total_count;
  83                }
  84        }
  85
  86        edata->load_count = load_count;
  87        edata->total_count = total_count;
  88
  89        return ret;
  90}
  91
  92/*
  93 * Must necessary function for devfreq simple-ondemand governor
  94 */
  95static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
  96{
  97        struct exynos_bus *bus = dev_get_drvdata(dev);
  98        struct dev_pm_opp *new_opp;
  99        unsigned long old_freq, new_freq, new_volt, tol;
 100        int ret = 0;
 101
 102        /* Get new opp-bus instance according to new bus clock */
 103        new_opp = devfreq_recommended_opp(dev, freq, flags);
 104        if (IS_ERR(new_opp)) {
 105                dev_err(dev, "failed to get recommended opp instance\n");
 106                return PTR_ERR(new_opp);
 107        }
 108
 109        new_freq = dev_pm_opp_get_freq(new_opp);
 110        new_volt = dev_pm_opp_get_voltage(new_opp);
 111        dev_pm_opp_put(new_opp);
 112
 113        old_freq = bus->curr_freq;
 114
 115        if (old_freq == new_freq)
 116                return 0;
 117        tol = new_volt * bus->voltage_tolerance / 100;
 118
 119        /* Change voltage and frequency according to new OPP level */
 120        mutex_lock(&bus->lock);
 121
 122        if (old_freq < new_freq) {
 123                ret = regulator_set_voltage_tol(bus->regulator, new_volt, tol);
 124                if (ret < 0) {
 125                        dev_err(bus->dev, "failed to set voltage\n");
 126                        goto out;
 127                }
 128        }
 129
 130        ret = clk_set_rate(bus->clk, new_freq);
 131        if (ret < 0) {
 132                dev_err(dev, "failed to change clock of bus\n");
 133                clk_set_rate(bus->clk, old_freq);
 134                goto out;
 135        }
 136
 137        if (old_freq > new_freq) {
 138                ret = regulator_set_voltage_tol(bus->regulator, new_volt, tol);
 139                if (ret < 0) {
 140                        dev_err(bus->dev, "failed to set voltage\n");
 141                        goto out;
 142                }
 143        }
 144        bus->curr_freq = new_freq;
 145
 146        dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
 147                        old_freq, new_freq, clk_get_rate(bus->clk));
 148out:
 149        mutex_unlock(&bus->lock);
 150
 151        return ret;
 152}
 153
 154static int exynos_bus_get_dev_status(struct device *dev,
 155                                     struct devfreq_dev_status *stat)
 156{
 157        struct exynos_bus *bus = dev_get_drvdata(dev);
 158        struct devfreq_event_data edata;
 159        int ret;
 160
 161        stat->current_frequency = bus->curr_freq;
 162
 163        ret = exynos_bus_get_event(bus, &edata);
 164        if (ret < 0) {
 165                stat->total_time = stat->busy_time = 0;
 166                goto err;
 167        }
 168
 169        stat->busy_time = (edata.load_count * 100) / bus->ratio;
 170        stat->total_time = edata.total_count;
 171
 172        dev_dbg(dev, "Usage of devfreq-event : %lu/%lu\n", stat->busy_time,
 173                                                        stat->total_time);
 174
 175err:
 176        ret = exynos_bus_set_event(bus);
 177        if (ret < 0) {
 178                dev_err(dev, "failed to set event to devfreq-event devices\n");
 179                return ret;
 180        }
 181
 182        return ret;
 183}
 184
 185static void exynos_bus_exit(struct device *dev)
 186{
 187        struct exynos_bus *bus = dev_get_drvdata(dev);
 188        int ret;
 189
 190        ret = exynos_bus_disable_edev(bus);
 191        if (ret < 0)
 192                dev_warn(dev, "failed to disable the devfreq-event devices\n");
 193
 194        if (bus->regulator)
 195                regulator_disable(bus->regulator);
 196
 197        dev_pm_opp_of_remove_table(dev);
 198        clk_disable_unprepare(bus->clk);
 199}
 200
 201/*
 202 * Must necessary function for devfreq passive governor
 203 */
 204static int exynos_bus_passive_target(struct device *dev, unsigned long *freq,
 205                                        u32 flags)
 206{
 207        struct exynos_bus *bus = dev_get_drvdata(dev);
 208        struct dev_pm_opp *new_opp;
 209        unsigned long old_freq, new_freq;
 210        int ret = 0;
 211
 212        /* Get new opp-bus instance according to new bus clock */
 213        new_opp = devfreq_recommended_opp(dev, freq, flags);
 214        if (IS_ERR(new_opp)) {
 215                dev_err(dev, "failed to get recommended opp instance\n");
 216                return PTR_ERR(new_opp);
 217        }
 218
 219        new_freq = dev_pm_opp_get_freq(new_opp);
 220        dev_pm_opp_put(new_opp);
 221
 222        old_freq = bus->curr_freq;
 223
 224        if (old_freq == new_freq)
 225                return 0;
 226
 227        /* Change the frequency according to new OPP level */
 228        mutex_lock(&bus->lock);
 229
 230        ret = clk_set_rate(bus->clk, new_freq);
 231        if (ret < 0) {
 232                dev_err(dev, "failed to set the clock of bus\n");
 233                goto out;
 234        }
 235
 236        *freq = new_freq;
 237        bus->curr_freq = new_freq;
 238
 239        dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
 240                        old_freq, new_freq, clk_get_rate(bus->clk));
 241out:
 242        mutex_unlock(&bus->lock);
 243
 244        return ret;
 245}
 246
 247static void exynos_bus_passive_exit(struct device *dev)
 248{
 249        struct exynos_bus *bus = dev_get_drvdata(dev);
 250
 251        dev_pm_opp_of_remove_table(dev);
 252        clk_disable_unprepare(bus->clk);
 253}
 254
 255static int exynos_bus_parent_parse_of(struct device_node *np,
 256                                        struct exynos_bus *bus)
 257{
 258        struct device *dev = bus->dev;
 259        int i, ret, count, size;
 260
 261        /* Get the regulator to provide each bus with the power */
 262        bus->regulator = devm_regulator_get(dev, "vdd");
 263        if (IS_ERR(bus->regulator)) {
 264                dev_err(dev, "failed to get VDD regulator\n");
 265                return PTR_ERR(bus->regulator);
 266        }
 267
 268        ret = regulator_enable(bus->regulator);
 269        if (ret < 0) {
 270                dev_err(dev, "failed to enable VDD regulator\n");
 271                return ret;
 272        }
 273
 274        /*
 275         * Get the devfreq-event devices to get the current utilization of
 276         * buses. This raw data will be used in devfreq ondemand governor.
 277         */
 278        count = devfreq_event_get_edev_count(dev);
 279        if (count < 0) {
 280                dev_err(dev, "failed to get the count of devfreq-event dev\n");
 281                ret = count;
 282                goto err_regulator;
 283        }
 284        bus->edev_count = count;
 285
 286        size = sizeof(*bus->edev) * count;
 287        bus->edev = devm_kzalloc(dev, size, GFP_KERNEL);
 288        if (!bus->edev) {
 289                ret = -ENOMEM;
 290                goto err_regulator;
 291        }
 292
 293        for (i = 0; i < count; i++) {
 294                bus->edev[i] = devfreq_event_get_edev_by_phandle(dev, i);
 295                if (IS_ERR(bus->edev[i])) {
 296                        ret = -EPROBE_DEFER;
 297                        goto err_regulator;
 298                }
 299        }
 300
 301        /*
 302         * Optionally, Get the saturation ratio according to Exynos SoC
 303         * When measuring the utilization of each AXI bus with devfreq-event
 304         * devices, the measured real cycle might be much lower than the
 305         * total cycle of bus during sampling rate. In result, the devfreq
 306         * simple-ondemand governor might not decide to change the current
 307         * frequency due to too utilization (= real cycle/total cycle).
 308         * So, this property is used to adjust the utilization when calculating
 309         * the busy_time in exynos_bus_get_dev_status().
 310         */
 311        if (of_property_read_u32(np, "exynos,saturation-ratio", &bus->ratio))
 312                bus->ratio = DEFAULT_SATURATION_RATIO;
 313
 314        if (of_property_read_u32(np, "exynos,voltage-tolerance",
 315                                        &bus->voltage_tolerance))
 316                bus->voltage_tolerance = DEFAULT_VOLTAGE_TOLERANCE;
 317
 318        return 0;
 319
 320err_regulator:
 321        regulator_disable(bus->regulator);
 322
 323        return ret;
 324}
 325
 326static int exynos_bus_parse_of(struct device_node *np,
 327                              struct exynos_bus *bus)
 328{
 329        struct device *dev = bus->dev;
 330        struct dev_pm_opp *opp;
 331        unsigned long rate;
 332        int ret;
 333
 334        /* Get the clock to provide each bus with source clock */
 335        bus->clk = devm_clk_get(dev, "bus");
 336        if (IS_ERR(bus->clk)) {
 337                dev_err(dev, "failed to get bus clock\n");
 338                return PTR_ERR(bus->clk);
 339        }
 340
 341        ret = clk_prepare_enable(bus->clk);
 342        if (ret < 0) {
 343                dev_err(dev, "failed to get enable clock\n");
 344                return ret;
 345        }
 346
 347        /* Get the freq and voltage from OPP table to scale the bus freq */
 348        ret = dev_pm_opp_of_add_table(dev);
 349        if (ret < 0) {
 350                dev_err(dev, "failed to get OPP table\n");
 351                goto err_clk;
 352        }
 353
 354        rate = clk_get_rate(bus->clk);
 355
 356        opp = devfreq_recommended_opp(dev, &rate, 0);
 357        if (IS_ERR(opp)) {
 358                dev_err(dev, "failed to find dev_pm_opp\n");
 359                ret = PTR_ERR(opp);
 360                goto err_opp;
 361        }
 362        bus->curr_freq = dev_pm_opp_get_freq(opp);
 363        dev_pm_opp_put(opp);
 364
 365        return 0;
 366
 367err_opp:
 368        dev_pm_opp_of_remove_table(dev);
 369err_clk:
 370        clk_disable_unprepare(bus->clk);
 371
 372        return ret;
 373}
 374
 375static int exynos_bus_probe(struct platform_device *pdev)
 376{
 377        struct device *dev = &pdev->dev;
 378        struct device_node *np = dev->of_node, *node;
 379        struct devfreq_dev_profile *profile;
 380        struct devfreq_simple_ondemand_data *ondemand_data;
 381        struct devfreq_passive_data *passive_data;
 382        struct devfreq *parent_devfreq;
 383        struct exynos_bus *bus;
 384        int ret, max_state;
 385        unsigned long min_freq, max_freq;
 386
 387        if (!np) {
 388                dev_err(dev, "failed to find devicetree node\n");
 389                return -EINVAL;
 390        }
 391
 392        bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
 393        if (!bus)
 394                return -ENOMEM;
 395        mutex_init(&bus->lock);
 396        bus->dev = &pdev->dev;
 397        platform_set_drvdata(pdev, bus);
 398
 399        /* Parse the device-tree to get the resource information */
 400        ret = exynos_bus_parse_of(np, bus);
 401        if (ret < 0)
 402                return ret;
 403
 404        profile = devm_kzalloc(dev, sizeof(*profile), GFP_KERNEL);
 405        if (!profile) {
 406                ret = -ENOMEM;
 407                goto err;
 408        }
 409
 410        node = of_parse_phandle(dev->of_node, "devfreq", 0);
 411        if (node) {
 412                of_node_put(node);
 413                goto passive;
 414        } else {
 415                ret = exynos_bus_parent_parse_of(np, bus);
 416        }
 417
 418        if (ret < 0)
 419                goto err;
 420
 421        /* Initialize the struct profile and governor data for parent device */
 422        profile->polling_ms = 50;
 423        profile->target = exynos_bus_target;
 424        profile->get_dev_status = exynos_bus_get_dev_status;
 425        profile->exit = exynos_bus_exit;
 426
 427        ondemand_data = devm_kzalloc(dev, sizeof(*ondemand_data), GFP_KERNEL);
 428        if (!ondemand_data) {
 429                ret = -ENOMEM;
 430                goto err;
 431        }
 432        ondemand_data->upthreshold = 40;
 433        ondemand_data->downdifferential = 5;
 434
 435        /* Add devfreq device to monitor and handle the exynos bus */
 436        bus->devfreq = devm_devfreq_add_device(dev, profile,
 437                                                DEVFREQ_GOV_SIMPLE_ONDEMAND,
 438                                                ondemand_data);
 439        if (IS_ERR(bus->devfreq)) {
 440                dev_err(dev, "failed to add devfreq device\n");
 441                ret = PTR_ERR(bus->devfreq);
 442                goto err;
 443        }
 444
 445        /* Register opp_notifier to catch the change of OPP  */
 446        ret = devm_devfreq_register_opp_notifier(dev, bus->devfreq);
 447        if (ret < 0) {
 448                dev_err(dev, "failed to register opp notifier\n");
 449                goto err;
 450        }
 451
 452        /*
 453         * Enable devfreq-event to get raw data which is used to determine
 454         * current bus load.
 455         */
 456        ret = exynos_bus_enable_edev(bus);
 457        if (ret < 0) {
 458                dev_err(dev, "failed to enable devfreq-event devices\n");
 459                goto err;
 460        }
 461
 462        ret = exynos_bus_set_event(bus);
 463        if (ret < 0) {
 464                dev_err(dev, "failed to set event to devfreq-event devices\n");
 465                goto err;
 466        }
 467
 468        goto out;
 469passive:
 470        /* Initialize the struct profile and governor data for passive device */
 471        profile->target = exynos_bus_passive_target;
 472        profile->exit = exynos_bus_passive_exit;
 473
 474        /* Get the instance of parent devfreq device */
 475        parent_devfreq = devfreq_get_devfreq_by_phandle(dev, 0);
 476        if (IS_ERR(parent_devfreq)) {
 477                ret = -EPROBE_DEFER;
 478                goto err;
 479        }
 480
 481        passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
 482        if (!passive_data) {
 483                ret = -ENOMEM;
 484                goto err;
 485        }
 486        passive_data->parent = parent_devfreq;
 487
 488        /* Add devfreq device for exynos bus with passive governor */
 489        bus->devfreq = devm_devfreq_add_device(dev, profile, DEVFREQ_GOV_PASSIVE,
 490                                                passive_data);
 491        if (IS_ERR(bus->devfreq)) {
 492                dev_err(dev,
 493                        "failed to add devfreq dev with passive governor\n");
 494                ret = PTR_ERR(bus->devfreq);
 495                goto err;
 496        }
 497
 498out:
 499        max_state = bus->devfreq->profile->max_state;
 500        min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
 501        max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
 502        pr_info("exynos-bus: new bus device registered: %s (%6ld KHz ~ %6ld KHz)\n",
 503                        dev_name(dev), min_freq, max_freq);
 504
 505        return 0;
 506
 507err:
 508        dev_pm_opp_of_remove_table(dev);
 509        clk_disable_unprepare(bus->clk);
 510
 511        return ret;
 512}
 513
 514static void exynos_bus_shutdown(struct platform_device *pdev)
 515{
 516        struct exynos_bus *bus = dev_get_drvdata(&pdev->dev);
 517
 518        devfreq_suspend_device(bus->devfreq);
 519}
 520
 521#ifdef CONFIG_PM_SLEEP
 522static int exynos_bus_resume(struct device *dev)
 523{
 524        struct exynos_bus *bus = dev_get_drvdata(dev);
 525        int ret;
 526
 527        ret = exynos_bus_enable_edev(bus);
 528        if (ret < 0) {
 529                dev_err(dev, "failed to enable the devfreq-event devices\n");
 530                return ret;
 531        }
 532
 533        return 0;
 534}
 535
 536static int exynos_bus_suspend(struct device *dev)
 537{
 538        struct exynos_bus *bus = dev_get_drvdata(dev);
 539        int ret;
 540
 541        ret = exynos_bus_disable_edev(bus);
 542        if (ret < 0) {
 543                dev_err(dev, "failed to disable the devfreq-event devices\n");
 544                return ret;
 545        }
 546
 547        return 0;
 548}
 549#endif
 550
 551static const struct dev_pm_ops exynos_bus_pm = {
 552        SET_SYSTEM_SLEEP_PM_OPS(exynos_bus_suspend, exynos_bus_resume)
 553};
 554
 555static const struct of_device_id exynos_bus_of_match[] = {
 556        { .compatible = "samsung,exynos-bus", },
 557        { /* sentinel */ },
 558};
 559MODULE_DEVICE_TABLE(of, exynos_bus_of_match);
 560
 561static struct platform_driver exynos_bus_platdrv = {
 562        .probe          = exynos_bus_probe,
 563        .shutdown       = exynos_bus_shutdown,
 564        .driver = {
 565                .name   = "exynos-bus",
 566                .pm     = &exynos_bus_pm,
 567                .of_match_table = of_match_ptr(exynos_bus_of_match),
 568        },
 569};
 570module_platform_driver(exynos_bus_platdrv);
 571
 572MODULE_DESCRIPTION("Generic Exynos Bus frequency driver");
 573MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
 574MODULE_LICENSE("GPL v2");
 575