at v3.9 1106 lines 30 kB view raw
1/* 2 * OMAP SmartReflex Voltage Control 3 * 4 * Author: Thara Gopinath <thara@ti.com> 5 * 6 * Copyright (C) 2012 Texas Instruments, Inc. 7 * Thara Gopinath <thara@ti.com> 8 * 9 * Copyright (C) 2008 Nokia Corporation 10 * Kalle Jokiniemi 11 * 12 * Copyright (C) 2007 Texas Instruments, Inc. 13 * Lesly A M <x0080970@ti.com> 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License version 2 as 17 * published by the Free Software Foundation. 18 */ 19 20#include <linux/module.h> 21#include <linux/interrupt.h> 22#include <linux/clk.h> 23#include <linux/io.h> 24#include <linux/debugfs.h> 25#include <linux/delay.h> 26#include <linux/slab.h> 27#include <linux/pm_runtime.h> 28#include <linux/power/smartreflex.h> 29 30#define SMARTREFLEX_NAME_LEN 16 31#define NVALUE_NAME_LEN 40 32#define SR_DISABLE_TIMEOUT 200 33 34/* sr_list contains all the instances of smartreflex module */ 35static LIST_HEAD(sr_list); 36 37static struct omap_sr_class_data *sr_class; 38static struct omap_sr_pmic_data *sr_pmic_data; 39static struct dentry *sr_dbg_dir; 40 41static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value) 42{ 43 __raw_writel(value, (sr->base + offset)); 44} 45 46static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, 47 u32 value) 48{ 49 u32 reg_val; 50 51 /* 52 * Smartreflex error config register is special as it contains 53 * certain status bits which if written a 1 into means a clear 54 * of those bits. So in order to make sure no accidental write of 55 * 1 happens to those status bits, do a clear of them in the read 56 * value. This mean this API doesn't rewrite values in these bits 57 * if they are currently set, but does allow the caller to write 58 * those bits. 59 */ 60 if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1) 61 mask |= ERRCONFIG_STATUS_V1_MASK; 62 else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2) 63 mask |= ERRCONFIG_VPBOUNDINTST_V2; 64 65 reg_val = __raw_readl(sr->base + offset); 66 reg_val &= ~mask; 67 68 value &= mask; 69 70 reg_val |= value; 71 72 __raw_writel(reg_val, (sr->base + offset)); 73} 74 75static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset) 76{ 77 return __raw_readl(sr->base + offset); 78} 79 80static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm) 81{ 82 struct omap_sr *sr_info; 83 84 if (!voltdm) { 85 pr_err("%s: Null voltage domain passed!\n", __func__); 86 return ERR_PTR(-EINVAL); 87 } 88 89 list_for_each_entry(sr_info, &sr_list, node) { 90 if (voltdm == sr_info->voltdm) 91 return sr_info; 92 } 93 94 return ERR_PTR(-ENODATA); 95} 96 97static irqreturn_t sr_interrupt(int irq, void *data) 98{ 99 struct omap_sr *sr_info = data; 100 u32 status = 0; 101 102 switch (sr_info->ip_type) { 103 case SR_TYPE_V1: 104 /* Read the status bits */ 105 status = sr_read_reg(sr_info, ERRCONFIG_V1); 106 107 /* Clear them by writing back */ 108 sr_write_reg(sr_info, ERRCONFIG_V1, status); 109 break; 110 case SR_TYPE_V2: 111 /* Read the status bits */ 112 status = sr_read_reg(sr_info, IRQSTATUS); 113 114 /* Clear them by writing back */ 115 sr_write_reg(sr_info, IRQSTATUS, status); 116 break; 117 default: 118 dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n", 119 sr_info->ip_type); 120 return IRQ_NONE; 121 } 122 123 if (sr_class->notify) 124 sr_class->notify(sr_info, status); 125 126 return IRQ_HANDLED; 127} 128 129static void sr_set_clk_length(struct omap_sr *sr) 130{ 131 struct clk *fck; 132 u32 fclk_speed; 133 134 fck = clk_get(&sr->pdev->dev, "fck"); 135 136 if (IS_ERR(fck)) { 137 dev_err(&sr->pdev->dev, "%s: unable to get fck for device %s\n", 138 __func__, dev_name(&sr->pdev->dev)); 139 return; 140 } 141 142 fclk_speed = clk_get_rate(fck); 143 clk_put(fck); 144 145 switch (fclk_speed) { 146 case 12000000: 147 sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK; 148 break; 149 case 13000000: 150 sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK; 151 break; 152 case 19200000: 153 sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK; 154 break; 155 case 26000000: 156 sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK; 157 break; 158 case 38400000: 159 sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK; 160 break; 161 default: 162 dev_err(&sr->pdev->dev, "%s: Invalid fclk rate: %d\n", 163 __func__, fclk_speed); 164 break; 165 } 166} 167 168static void sr_start_vddautocomp(struct omap_sr *sr) 169{ 170 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) { 171 dev_warn(&sr->pdev->dev, 172 "%s: smartreflex class driver not registered\n", 173 __func__); 174 return; 175 } 176 177 if (!sr_class->enable(sr)) 178 sr->autocomp_active = true; 179} 180 181static void sr_stop_vddautocomp(struct omap_sr *sr) 182{ 183 if (!sr_class || !(sr_class->disable)) { 184 dev_warn(&sr->pdev->dev, 185 "%s: smartreflex class driver not registered\n", 186 __func__); 187 return; 188 } 189 190 if (sr->autocomp_active) { 191 sr_class->disable(sr, 1); 192 sr->autocomp_active = false; 193 } 194} 195 196/* 197 * This function handles the intializations which have to be done 198 * only when both sr device and class driver regiter has 199 * completed. This will be attempted to be called from both sr class 200 * driver register and sr device intializtion API's. Only one call 201 * will ultimately succeed. 202 * 203 * Currently this function registers interrupt handler for a particular SR 204 * if smartreflex class driver is already registered and has 205 * requested for interrupts and the SR interrupt line in present. 206 */ 207static int sr_late_init(struct omap_sr *sr_info) 208{ 209 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; 210 struct resource *mem; 211 int ret = 0; 212 213 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { 214 ret = request_irq(sr_info->irq, sr_interrupt, 215 0, sr_info->name, sr_info); 216 if (ret) 217 goto error; 218 disable_irq(sr_info->irq); 219 } 220 221 if (pdata && pdata->enable_on_init) 222 sr_start_vddautocomp(sr_info); 223 224 return ret; 225 226error: 227 iounmap(sr_info->base); 228 mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); 229 release_mem_region(mem->start, resource_size(mem)); 230 list_del(&sr_info->node); 231 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" 232 "interrupt handler. Smartreflex will" 233 "not function as desired\n", __func__); 234 kfree(sr_info); 235 236 return ret; 237} 238 239static void sr_v1_disable(struct omap_sr *sr) 240{ 241 int timeout = 0; 242 int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | 243 ERRCONFIG_MCUBOUNDINTST; 244 245 /* Enable MCUDisableAcknowledge interrupt */ 246 sr_modify_reg(sr, ERRCONFIG_V1, 247 ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN); 248 249 /* SRCONFIG - disable SR */ 250 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); 251 252 /* Disable all other SR interrupts and clear the status as needed */ 253 if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1) 254 errconf_val |= ERRCONFIG_VPBOUNDINTST_V1; 255 sr_modify_reg(sr, ERRCONFIG_V1, 256 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | 257 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), 258 errconf_val); 259 260 /* 261 * Wait for SR to be disabled. 262 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us. 263 */ 264 sr_test_cond_timeout((sr_read_reg(sr, ERRCONFIG_V1) & 265 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT, 266 timeout); 267 268 if (timeout >= SR_DISABLE_TIMEOUT) 269 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", 270 __func__); 271 272 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */ 273 sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN, 274 ERRCONFIG_MCUDISACKINTST); 275} 276 277static void sr_v2_disable(struct omap_sr *sr) 278{ 279 int timeout = 0; 280 281 /* Enable MCUDisableAcknowledge interrupt */ 282 sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT); 283 284 /* SRCONFIG - disable SR */ 285 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); 286 287 /* 288 * Disable all other SR interrupts and clear the status 289 * write to status register ONLY on need basis - only if status 290 * is set. 291 */ 292 if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2) 293 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, 294 ERRCONFIG_VPBOUNDINTST_V2); 295 else 296 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, 297 0x0); 298 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | 299 IRQENABLE_MCUVALIDINT | 300 IRQENABLE_MCUBOUNDSINT)); 301 sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT | 302 IRQSTATUS_MCVALIDINT | 303 IRQSTATUS_MCBOUNDSINT)); 304 305 /* 306 * Wait for SR to be disabled. 307 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us. 308 */ 309 sr_test_cond_timeout((sr_read_reg(sr, IRQSTATUS) & 310 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT, 311 timeout); 312 313 if (timeout >= SR_DISABLE_TIMEOUT) 314 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", 315 __func__); 316 317 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */ 318 sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT); 319 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT); 320} 321 322static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row( 323 struct omap_sr *sr, u32 efuse_offs) 324{ 325 int i; 326 327 if (!sr->nvalue_table) { 328 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n", 329 __func__); 330 return NULL; 331 } 332 333 for (i = 0; i < sr->nvalue_count; i++) { 334 if (sr->nvalue_table[i].efuse_offs == efuse_offs) 335 return &sr->nvalue_table[i]; 336 } 337 338 return NULL; 339} 340 341/* Public Functions */ 342 343/** 344 * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the 345 * error generator module. 346 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 347 * 348 * This API is to be called from the smartreflex class driver to 349 * configure the error generator module inside the smartreflex module. 350 * SR settings if using the ERROR module inside Smartreflex. 351 * SR CLASS 3 by default uses only the ERROR module where as 352 * SR CLASS 2 can choose between ERROR module and MINMAXAVG 353 * module. Returns 0 on success and error value in case of failure. 354 */ 355int sr_configure_errgen(struct voltagedomain *voltdm) 356{ 357 u32 sr_config, sr_errconfig, errconfig_offs; 358 u32 vpboundint_en, vpboundint_st; 359 u32 senp_en = 0, senn_en = 0; 360 u8 senp_shift, senn_shift; 361 struct omap_sr *sr = _sr_lookup(voltdm); 362 363 if (IS_ERR(sr)) { 364 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 365 return PTR_ERR(sr); 366 } 367 368 if (!sr->clk_length) 369 sr_set_clk_length(sr); 370 371 senp_en = sr->senp_mod; 372 senn_en = sr->senn_mod; 373 374 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | 375 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; 376 377 switch (sr->ip_type) { 378 case SR_TYPE_V1: 379 sr_config |= SRCONFIG_DELAYCTRL; 380 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; 381 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; 382 errconfig_offs = ERRCONFIG_V1; 383 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; 384 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; 385 break; 386 case SR_TYPE_V2: 387 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; 388 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; 389 errconfig_offs = ERRCONFIG_V2; 390 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; 391 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; 392 break; 393 default: 394 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" 395 "module without specifying the ip\n", __func__); 396 return -EINVAL; 397 } 398 399 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift)); 400 sr_write_reg(sr, SRCONFIG, sr_config); 401 sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) | 402 (sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) | 403 (sr->err_minlimit << ERRCONFIG_ERRMINLIMIT_SHIFT); 404 sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK | 405 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK), 406 sr_errconfig); 407 408 /* Enabling the interrupts if the ERROR module is used */ 409 sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st), 410 vpboundint_en); 411 412 return 0; 413} 414 415/** 416 * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component 417 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 418 * 419 * This API is to be called from the smartreflex class driver to 420 * disable the error generator module inside the smartreflex module. 421 * 422 * Returns 0 on success and error value in case of failure. 423 */ 424int sr_disable_errgen(struct voltagedomain *voltdm) 425{ 426 u32 errconfig_offs; 427 u32 vpboundint_en, vpboundint_st; 428 struct omap_sr *sr = _sr_lookup(voltdm); 429 430 if (IS_ERR(sr)) { 431 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 432 return PTR_ERR(sr); 433 } 434 435 switch (sr->ip_type) { 436 case SR_TYPE_V1: 437 errconfig_offs = ERRCONFIG_V1; 438 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; 439 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; 440 break; 441 case SR_TYPE_V2: 442 errconfig_offs = ERRCONFIG_V2; 443 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; 444 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; 445 break; 446 default: 447 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" 448 "module without specifying the ip\n", __func__); 449 return -EINVAL; 450 } 451 452 /* Disable the interrupts of ERROR module */ 453 sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0); 454 455 /* Disable the Sensor and errorgen */ 456 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0); 457 458 return 0; 459} 460 461/** 462 * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the 463 * minmaxavg module. 464 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 465 * 466 * This API is to be called from the smartreflex class driver to 467 * configure the minmaxavg module inside the smartreflex module. 468 * SR settings if using the ERROR module inside Smartreflex. 469 * SR CLASS 3 by default uses only the ERROR module where as 470 * SR CLASS 2 can choose between ERROR module and MINMAXAVG 471 * module. Returns 0 on success and error value in case of failure. 472 */ 473int sr_configure_minmax(struct voltagedomain *voltdm) 474{ 475 u32 sr_config, sr_avgwt; 476 u32 senp_en = 0, senn_en = 0; 477 u8 senp_shift, senn_shift; 478 struct omap_sr *sr = _sr_lookup(voltdm); 479 480 if (IS_ERR(sr)) { 481 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 482 return PTR_ERR(sr); 483 } 484 485 if (!sr->clk_length) 486 sr_set_clk_length(sr); 487 488 senp_en = sr->senp_mod; 489 senn_en = sr->senn_mod; 490 491 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | 492 SRCONFIG_SENENABLE | 493 (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); 494 495 switch (sr->ip_type) { 496 case SR_TYPE_V1: 497 sr_config |= SRCONFIG_DELAYCTRL; 498 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; 499 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; 500 break; 501 case SR_TYPE_V2: 502 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; 503 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; 504 break; 505 default: 506 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" 507 "module without specifying the ip\n", __func__); 508 return -EINVAL; 509 } 510 511 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift)); 512 sr_write_reg(sr, SRCONFIG, sr_config); 513 sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) | 514 (sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT); 515 sr_write_reg(sr, AVGWEIGHT, sr_avgwt); 516 517 /* 518 * Enabling the interrupts if MINMAXAVG module is used. 519 * TODO: check if all the interrupts are mandatory 520 */ 521 switch (sr->ip_type) { 522 case SR_TYPE_V1: 523 sr_modify_reg(sr, ERRCONFIG_V1, 524 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | 525 ERRCONFIG_MCUBOUNDINTEN), 526 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | 527 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | 528 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); 529 break; 530 case SR_TYPE_V2: 531 sr_write_reg(sr, IRQSTATUS, 532 IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | 533 IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); 534 sr_write_reg(sr, IRQENABLE_SET, 535 IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | 536 IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); 537 break; 538 default: 539 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" 540 "module without specifying the ip\n", __func__); 541 return -EINVAL; 542 } 543 544 return 0; 545} 546 547/** 548 * sr_enable() - Enables the smartreflex module. 549 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 550 * @volt: The voltage at which the Voltage domain associated with 551 * the smartreflex module is operating at. 552 * This is required only to program the correct Ntarget value. 553 * 554 * This API is to be called from the smartreflex class driver to 555 * enable a smartreflex module. Returns 0 on success. Returns error 556 * value if the voltage passed is wrong or if ntarget value is wrong. 557 */ 558int sr_enable(struct voltagedomain *voltdm, unsigned long volt) 559{ 560 struct omap_volt_data *volt_data; 561 struct omap_sr *sr = _sr_lookup(voltdm); 562 struct omap_sr_nvalue_table *nvalue_row; 563 int ret; 564 565 if (IS_ERR(sr)) { 566 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 567 return PTR_ERR(sr); 568 } 569 570 volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); 571 572 if (IS_ERR(volt_data)) { 573 dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" 574 "for nominal voltage %ld\n", __func__, volt); 575 return PTR_ERR(volt_data); 576 } 577 578 nvalue_row = sr_retrieve_nvalue_row(sr, volt_data->sr_efuse_offs); 579 580 if (!nvalue_row) { 581 dev_warn(&sr->pdev->dev, "%s: failure getting SR data for this voltage %ld\n", 582 __func__, volt); 583 return -ENODATA; 584 } 585 586 /* errminlimit is opp dependent and hence linked to voltage */ 587 sr->err_minlimit = nvalue_row->errminlimit; 588 589 pm_runtime_get_sync(&sr->pdev->dev); 590 591 /* Check if SR is already enabled. If yes do nothing */ 592 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) 593 return 0; 594 595 /* Configure SR */ 596 ret = sr_class->configure(sr); 597 if (ret) 598 return ret; 599 600 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_row->nvalue); 601 602 /* SRCONFIG - enable SR */ 603 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE); 604 return 0; 605} 606 607/** 608 * sr_disable() - Disables the smartreflex module. 609 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 610 * 611 * This API is to be called from the smartreflex class driver to 612 * disable a smartreflex module. 613 */ 614void sr_disable(struct voltagedomain *voltdm) 615{ 616 struct omap_sr *sr = _sr_lookup(voltdm); 617 618 if (IS_ERR(sr)) { 619 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 620 return; 621 } 622 623 /* Check if SR clocks are already disabled. If yes do nothing */ 624 if (pm_runtime_suspended(&sr->pdev->dev)) 625 return; 626 627 /* 628 * Disable SR if only it is indeed enabled. Else just 629 * disable the clocks. 630 */ 631 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { 632 switch (sr->ip_type) { 633 case SR_TYPE_V1: 634 sr_v1_disable(sr); 635 break; 636 case SR_TYPE_V2: 637 sr_v2_disable(sr); 638 break; 639 default: 640 dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n", 641 sr->ip_type); 642 } 643 } 644 645 pm_runtime_put_sync_suspend(&sr->pdev->dev); 646} 647 648/** 649 * sr_register_class() - API to register a smartreflex class parameters. 650 * @class_data: The structure containing various sr class specific data. 651 * 652 * This API is to be called by the smartreflex class driver to register itself 653 * with the smartreflex driver during init. Returns 0 on success else the 654 * error value. 655 */ 656int sr_register_class(struct omap_sr_class_data *class_data) 657{ 658 struct omap_sr *sr_info; 659 660 if (!class_data) { 661 pr_warning("%s:, Smartreflex class data passed is NULL\n", 662 __func__); 663 return -EINVAL; 664 } 665 666 if (sr_class) { 667 pr_warning("%s: Smartreflex class driver already registered\n", 668 __func__); 669 return -EBUSY; 670 } 671 672 sr_class = class_data; 673 674 /* 675 * Call into late init to do intializations that require 676 * both sr driver and sr class driver to be initiallized. 677 */ 678 list_for_each_entry(sr_info, &sr_list, node) 679 sr_late_init(sr_info); 680 681 return 0; 682} 683 684/** 685 * omap_sr_enable() - API to enable SR clocks and to call into the 686 * registered smartreflex class enable API. 687 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 688 * 689 * This API is to be called from the kernel in order to enable 690 * a particular smartreflex module. This API will do the initial 691 * configurations to turn on the smartreflex module and in turn call 692 * into the registered smartreflex class enable API. 693 */ 694void omap_sr_enable(struct voltagedomain *voltdm) 695{ 696 struct omap_sr *sr = _sr_lookup(voltdm); 697 698 if (IS_ERR(sr)) { 699 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 700 return; 701 } 702 703 if (!sr->autocomp_active) 704 return; 705 706 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) { 707 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" 708 "registered\n", __func__); 709 return; 710 } 711 712 sr_class->enable(sr); 713} 714 715/** 716 * omap_sr_disable() - API to disable SR without resetting the voltage 717 * processor voltage 718 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 719 * 720 * This API is to be called from the kernel in order to disable 721 * a particular smartreflex module. This API will in turn call 722 * into the registered smartreflex class disable API. This API will tell 723 * the smartreflex class disable not to reset the VP voltage after 724 * disabling smartreflex. 725 */ 726void omap_sr_disable(struct voltagedomain *voltdm) 727{ 728 struct omap_sr *sr = _sr_lookup(voltdm); 729 730 if (IS_ERR(sr)) { 731 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 732 return; 733 } 734 735 if (!sr->autocomp_active) 736 return; 737 738 if (!sr_class || !(sr_class->disable)) { 739 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" 740 "registered\n", __func__); 741 return; 742 } 743 744 sr_class->disable(sr, 0); 745} 746 747/** 748 * omap_sr_disable_reset_volt() - API to disable SR and reset the 749 * voltage processor voltage 750 * @voltdm: VDD pointer to which the SR module to be configured belongs to. 751 * 752 * This API is to be called from the kernel in order to disable 753 * a particular smartreflex module. This API will in turn call 754 * into the registered smartreflex class disable API. This API will tell 755 * the smartreflex class disable to reset the VP voltage after 756 * disabling smartreflex. 757 */ 758void omap_sr_disable_reset_volt(struct voltagedomain *voltdm) 759{ 760 struct omap_sr *sr = _sr_lookup(voltdm); 761 762 if (IS_ERR(sr)) { 763 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__); 764 return; 765 } 766 767 if (!sr->autocomp_active) 768 return; 769 770 if (!sr_class || !(sr_class->disable)) { 771 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" 772 "registered\n", __func__); 773 return; 774 } 775 776 sr_class->disable(sr, 1); 777} 778 779/** 780 * omap_sr_register_pmic() - API to register pmic specific info. 781 * @pmic_data: The structure containing pmic specific data. 782 * 783 * This API is to be called from the PMIC specific code to register with 784 * smartreflex driver pmic specific info. Currently the only info required 785 * is the smartreflex init on the PMIC side. 786 */ 787void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data) 788{ 789 if (!pmic_data) { 790 pr_warning("%s: Trying to register NULL PMIC data structure" 791 "with smartreflex\n", __func__); 792 return; 793 } 794 795 sr_pmic_data = pmic_data; 796} 797 798/* PM Debug FS entries to enable and disable smartreflex. */ 799static int omap_sr_autocomp_show(void *data, u64 *val) 800{ 801 struct omap_sr *sr_info = data; 802 803 if (!sr_info) { 804 pr_warning("%s: omap_sr struct not found\n", __func__); 805 return -EINVAL; 806 } 807 808 *val = sr_info->autocomp_active; 809 810 return 0; 811} 812 813static int omap_sr_autocomp_store(void *data, u64 val) 814{ 815 struct omap_sr *sr_info = data; 816 817 if (!sr_info) { 818 pr_warning("%s: omap_sr struct not found\n", __func__); 819 return -EINVAL; 820 } 821 822 /* Sanity check */ 823 if (val > 1) { 824 pr_warning("%s: Invalid argument %lld\n", __func__, val); 825 return -EINVAL; 826 } 827 828 /* control enable/disable only if there is a delta in value */ 829 if (sr_info->autocomp_active != val) { 830 if (!val) 831 sr_stop_vddautocomp(sr_info); 832 else 833 sr_start_vddautocomp(sr_info); 834 } 835 836 return 0; 837} 838 839DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, 840 omap_sr_autocomp_store, "%llu\n"); 841 842static int __init omap_sr_probe(struct platform_device *pdev) 843{ 844 struct omap_sr *sr_info; 845 struct omap_sr_data *pdata = pdev->dev.platform_data; 846 struct resource *mem, *irq; 847 struct dentry *nvalue_dir; 848 int i, ret = 0; 849 850 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); 851 if (!sr_info) { 852 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", 853 __func__); 854 return -ENOMEM; 855 } 856 857 platform_set_drvdata(pdev, sr_info); 858 859 if (!pdata) { 860 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 861 ret = -EINVAL; 862 goto err_free_devinfo; 863 } 864 865 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 866 if (!mem) { 867 dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 868 ret = -ENODEV; 869 goto err_free_devinfo; 870 } 871 872 mem = request_mem_region(mem->start, resource_size(mem), 873 dev_name(&pdev->dev)); 874 if (!mem) { 875 dev_err(&pdev->dev, "%s: no mem region\n", __func__); 876 ret = -EBUSY; 877 goto err_free_devinfo; 878 } 879 880 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 881 882 pm_runtime_enable(&pdev->dev); 883 pm_runtime_irq_safe(&pdev->dev); 884 885 sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name); 886 if (!sr_info->name) { 887 dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n", 888 __func__); 889 ret = -ENOMEM; 890 goto err_release_region; 891 } 892 893 sr_info->pdev = pdev; 894 sr_info->srid = pdev->id; 895 sr_info->voltdm = pdata->voltdm; 896 sr_info->nvalue_table = pdata->nvalue_table; 897 sr_info->nvalue_count = pdata->nvalue_count; 898 sr_info->senn_mod = pdata->senn_mod; 899 sr_info->senp_mod = pdata->senp_mod; 900 sr_info->err_weight = pdata->err_weight; 901 sr_info->err_maxlimit = pdata->err_maxlimit; 902 sr_info->accum_data = pdata->accum_data; 903 sr_info->senn_avgweight = pdata->senn_avgweight; 904 sr_info->senp_avgweight = pdata->senp_avgweight; 905 sr_info->autocomp_active = false; 906 sr_info->ip_type = pdata->ip_type; 907 908 sr_info->base = ioremap(mem->start, resource_size(mem)); 909 if (!sr_info->base) { 910 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 911 ret = -ENOMEM; 912 goto err_free_name; 913 } 914 915 if (irq) 916 sr_info->irq = irq->start; 917 918 sr_set_clk_length(sr_info); 919 920 list_add(&sr_info->node, &sr_list); 921 922 /* 923 * Call into late init to do intializations that require 924 * both sr driver and sr class driver to be initiallized. 925 */ 926 if (sr_class) { 927 ret = sr_late_init(sr_info); 928 if (ret) { 929 pr_warning("%s: Error in SR late init\n", __func__); 930 goto err_iounmap; 931 } 932 } 933 934 dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); 935 if (!sr_dbg_dir) { 936 sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); 937 if (IS_ERR_OR_NULL(sr_dbg_dir)) { 938 ret = PTR_ERR(sr_dbg_dir); 939 pr_err("%s:sr debugfs dir creation failed(%d)\n", 940 __func__, ret); 941 goto err_iounmap; 942 } 943 } 944 945 sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir); 946 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { 947 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", 948 __func__); 949 ret = PTR_ERR(sr_info->dbg_dir); 950 goto err_debugfs; 951 } 952 953 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, 954 sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops); 955 (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, 956 &sr_info->err_weight); 957 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, 958 &sr_info->err_maxlimit); 959 960 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); 961 if (IS_ERR_OR_NULL(nvalue_dir)) { 962 dev_err(&pdev->dev, "%s: Unable to create debugfs directory" 963 "for n-values\n", __func__); 964 ret = PTR_ERR(nvalue_dir); 965 goto err_debugfs; 966 } 967 968 if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) { 969 dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n", 970 __func__, sr_info->name); 971 972 ret = -ENODATA; 973 goto err_debugfs; 974 } 975 976 for (i = 0; i < sr_info->nvalue_count; i++) { 977 char name[NVALUE_NAME_LEN + 1]; 978 979 snprintf(name, sizeof(name), "volt_%lu", 980 sr_info->nvalue_table[i].volt_nominal); 981 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, 982 &(sr_info->nvalue_table[i].nvalue)); 983 snprintf(name, sizeof(name), "errminlimit_%lu", 984 sr_info->nvalue_table[i].volt_nominal); 985 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, 986 &(sr_info->nvalue_table[i].errminlimit)); 987 988 } 989 990 return ret; 991 992err_debugfs: 993 debugfs_remove_recursive(sr_info->dbg_dir); 994err_iounmap: 995 list_del(&sr_info->node); 996 iounmap(sr_info->base); 997err_free_name: 998 kfree(sr_info->name); 999err_release_region: 1000 release_mem_region(mem->start, resource_size(mem)); 1001err_free_devinfo: 1002 kfree(sr_info); 1003 1004 return ret; 1005} 1006 1007static int omap_sr_remove(struct platform_device *pdev) 1008{ 1009 struct omap_sr_data *pdata = pdev->dev.platform_data; 1010 struct omap_sr *sr_info; 1011 struct resource *mem; 1012 1013 if (!pdata) { 1014 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 1015 return -EINVAL; 1016 } 1017 1018 sr_info = _sr_lookup(pdata->voltdm); 1019 if (IS_ERR(sr_info)) { 1020 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", 1021 __func__); 1022 return PTR_ERR(sr_info); 1023 } 1024 1025 if (sr_info->autocomp_active) 1026 sr_stop_vddautocomp(sr_info); 1027 if (sr_info->dbg_dir) 1028 debugfs_remove_recursive(sr_info->dbg_dir); 1029 1030 list_del(&sr_info->node); 1031 iounmap(sr_info->base); 1032 kfree(sr_info->name); 1033 kfree(sr_info); 1034 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1035 release_mem_region(mem->start, resource_size(mem)); 1036 1037 return 0; 1038} 1039 1040static void omap_sr_shutdown(struct platform_device *pdev) 1041{ 1042 struct omap_sr_data *pdata = pdev->dev.platform_data; 1043 struct omap_sr *sr_info; 1044 1045 if (!pdata) { 1046 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 1047 return; 1048 } 1049 1050 sr_info = _sr_lookup(pdata->voltdm); 1051 if (IS_ERR(sr_info)) { 1052 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", 1053 __func__); 1054 return; 1055 } 1056 1057 if (sr_info->autocomp_active) 1058 sr_stop_vddautocomp(sr_info); 1059 1060 return; 1061} 1062 1063static struct platform_driver smartreflex_driver = { 1064 .remove = omap_sr_remove, 1065 .shutdown = omap_sr_shutdown, 1066 .driver = { 1067 .name = "smartreflex", 1068 }, 1069}; 1070 1071static int __init sr_init(void) 1072{ 1073 int ret = 0; 1074 1075 /* 1076 * sr_init is a late init. If by then a pmic specific API is not 1077 * registered either there is no need for anything to be done on 1078 * the PMIC side or somebody has forgotten to register a PMIC 1079 * handler. Warn for the second condition. 1080 */ 1081 if (sr_pmic_data && sr_pmic_data->sr_pmic_init) 1082 sr_pmic_data->sr_pmic_init(); 1083 else 1084 pr_warning("%s: No PMIC hook to init smartreflex\n", __func__); 1085 1086 ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe); 1087 if (ret) { 1088 pr_err("%s: platform driver register failed for SR\n", 1089 __func__); 1090 return ret; 1091 } 1092 1093 return 0; 1094} 1095late_initcall(sr_init); 1096 1097static void __exit sr_exit(void) 1098{ 1099 platform_driver_unregister(&smartreflex_driver); 1100} 1101module_exit(sr_exit); 1102 1103MODULE_DESCRIPTION("OMAP Smartreflex Driver"); 1104MODULE_LICENSE("GPL"); 1105MODULE_ALIAS("platform:" DRIVER_NAME); 1106MODULE_AUTHOR("Texas Instruments Inc");