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