arche-platform.c (18268B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Arche Platform driver to enable Unipro link. 4 * 5 * Copyright 2014-2015 Google Inc. 6 * Copyright 2014-2015 Linaro Ltd. 7 */ 8 9#include <linux/clk.h> 10#include <linux/delay.h> 11#include <linux/gpio/consumer.h> 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/of_platform.h> 15#include <linux/pinctrl/consumer.h> 16#include <linux/platform_device.h> 17#include <linux/pm.h> 18#include <linux/interrupt.h> 19#include <linux/irq.h> 20#include <linux/suspend.h> 21#include <linux/time.h> 22#include <linux/greybus.h> 23#include "arche_platform.h" 24 25#if IS_ENABLED(CONFIG_USB_HSIC_USB3613) 26#include <linux/usb/usb3613.h> 27#else 28static inline int usb3613_hub_mode_ctrl(bool unused) 29{ 30 return 0; 31} 32#endif 33 34#define WD_COLDBOOT_PULSE_WIDTH_MS 30 35 36enum svc_wakedetect_state { 37 WD_STATE_IDLE, /* Default state = pulled high/low */ 38 WD_STATE_BOOT_INIT, /* WD = falling edge (low) */ 39 WD_STATE_COLDBOOT_TRIG, /* WD = rising edge (high), > 30msec */ 40 WD_STATE_STANDBYBOOT_TRIG, /* As of now not used ?? */ 41 WD_STATE_COLDBOOT_START, /* Cold boot process started */ 42 WD_STATE_STANDBYBOOT_START, /* Not used */ 43}; 44 45struct arche_platform_drvdata { 46 /* Control GPIO signals to and from AP <=> SVC */ 47 struct gpio_desc *svc_reset; 48 bool is_reset_act_hi; 49 struct gpio_desc *svc_sysboot; 50 struct gpio_desc *wake_detect; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */ 51 52 enum arche_platform_state state; 53 54 struct gpio_desc *svc_refclk_req; 55 struct clk *svc_ref_clk; 56 57 struct pinctrl *pinctrl; 58 struct pinctrl_state *pin_default; 59 60 int num_apbs; 61 62 enum svc_wakedetect_state wake_detect_state; 63 int wake_detect_irq; 64 spinlock_t wake_lock; /* Protect wake_detect_state */ 65 struct mutex platform_state_mutex; /* Protect state */ 66 unsigned long wake_detect_start; 67 struct notifier_block pm_notifier; 68 69 struct device *dev; 70}; 71 72/* Requires calling context to hold arche_pdata->platform_state_mutex */ 73static void arche_platform_set_state(struct arche_platform_drvdata *arche_pdata, 74 enum arche_platform_state state) 75{ 76 arche_pdata->state = state; 77} 78 79/* Requires arche_pdata->wake_lock is held by calling context */ 80static void arche_platform_set_wake_detect_state(struct arche_platform_drvdata *arche_pdata, 81 enum svc_wakedetect_state state) 82{ 83 arche_pdata->wake_detect_state = state; 84} 85 86static inline void svc_reset_onoff(struct gpio_desc *gpio, bool onoff) 87{ 88 gpiod_set_raw_value(gpio, onoff); 89} 90 91static int apb_cold_boot(struct device *dev, void *data) 92{ 93 int ret; 94 95 ret = apb_ctrl_coldboot(dev); 96 if (ret) 97 dev_warn(dev, "failed to coldboot\n"); 98 99 /*Child nodes are independent, so do not exit coldboot operation */ 100 return 0; 101} 102 103static int apb_poweroff(struct device *dev, void *data) 104{ 105 apb_ctrl_poweroff(dev); 106 107 /* Enable HUB3613 into HUB mode. */ 108 if (usb3613_hub_mode_ctrl(false)) 109 dev_warn(dev, "failed to control hub device\n"); 110 111 return 0; 112} 113 114static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata) 115{ 116 /* Enable interrupt here, to read event back from SVC */ 117 enable_irq(arche_pdata->wake_detect_irq); 118} 119 120static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid) 121{ 122 struct arche_platform_drvdata *arche_pdata = devid; 123 unsigned long flags; 124 125 spin_lock_irqsave(&arche_pdata->wake_lock, flags); 126 if (arche_pdata->wake_detect_state != WD_STATE_COLDBOOT_TRIG) { 127 /* Something is wrong */ 128 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); 129 return IRQ_HANDLED; 130 } 131 132 arche_platform_set_wake_detect_state(arche_pdata, 133 WD_STATE_COLDBOOT_START); 134 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); 135 136 /* It should complete power cycle, so first make sure it is poweroff */ 137 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); 138 139 /* Bring APB out of reset: cold boot sequence */ 140 device_for_each_child(arche_pdata->dev, NULL, apb_cold_boot); 141 142 /* Enable HUB3613 into HUB mode. */ 143 if (usb3613_hub_mode_ctrl(true)) 144 dev_warn(arche_pdata->dev, "failed to control hub device\n"); 145 146 spin_lock_irqsave(&arche_pdata->wake_lock, flags); 147 arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE); 148 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); 149 150 return IRQ_HANDLED; 151} 152 153static irqreturn_t arche_platform_wd_irq(int irq, void *devid) 154{ 155 struct arche_platform_drvdata *arche_pdata = devid; 156 unsigned long flags; 157 158 spin_lock_irqsave(&arche_pdata->wake_lock, flags); 159 160 if (gpiod_get_value(arche_pdata->wake_detect)) { 161 /* wake/detect rising */ 162 163 /* 164 * If wake/detect line goes high after low, within less than 165 * 30msec, then standby boot sequence is initiated, which is not 166 * supported/implemented as of now. So ignore it. 167 */ 168 if (arche_pdata->wake_detect_state == WD_STATE_BOOT_INIT) { 169 if (time_before(jiffies, 170 arche_pdata->wake_detect_start + 171 msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) { 172 arche_platform_set_wake_detect_state(arche_pdata, 173 WD_STATE_IDLE); 174 } else { 175 /* 176 * Check we are not in middle of irq thread 177 * already 178 */ 179 if (arche_pdata->wake_detect_state != 180 WD_STATE_COLDBOOT_START) { 181 arche_platform_set_wake_detect_state(arche_pdata, 182 WD_STATE_COLDBOOT_TRIG); 183 spin_unlock_irqrestore(&arche_pdata->wake_lock, 184 flags); 185 return IRQ_WAKE_THREAD; 186 } 187 } 188 } 189 } else { 190 /* wake/detect falling */ 191 if (arche_pdata->wake_detect_state == WD_STATE_IDLE) { 192 arche_pdata->wake_detect_start = jiffies; 193 /* 194 * In the beginning, when wake/detect goes low 195 * (first time), we assume it is meant for coldboot 196 * and set the flag. If wake/detect line stays low 197 * beyond 30msec, then it is coldboot else fallback 198 * to standby boot. 199 */ 200 arche_platform_set_wake_detect_state(arche_pdata, 201 WD_STATE_BOOT_INIT); 202 } 203 } 204 205 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); 206 207 return IRQ_HANDLED; 208} 209 210/* 211 * Requires arche_pdata->platform_state_mutex to be held 212 */ 213static int 214arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) 215{ 216 int ret; 217 218 if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE) 219 return 0; 220 221 dev_info(arche_pdata->dev, "Booting from cold boot state\n"); 222 223 svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); 224 225 gpiod_set_value(arche_pdata->svc_sysboot, 0); 226 usleep_range(100, 200); 227 228 ret = clk_prepare_enable(arche_pdata->svc_ref_clk); 229 if (ret) { 230 dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n", 231 ret); 232 return ret; 233 } 234 235 /* bring SVC out of reset */ 236 svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); 237 238 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE); 239 240 return 0; 241} 242 243/* 244 * Requires arche_pdata->platform_state_mutex to be held 245 */ 246static int 247arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) 248{ 249 int ret; 250 251 if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING) 252 return 0; 253 254 dev_info(arche_pdata->dev, "Switching to FW flashing state\n"); 255 256 svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); 257 258 gpiod_set_value(arche_pdata->svc_sysboot, 1); 259 260 usleep_range(100, 200); 261 262 ret = clk_prepare_enable(arche_pdata->svc_ref_clk); 263 if (ret) { 264 dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n", 265 ret); 266 return ret; 267 } 268 269 svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi); 270 271 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING); 272 273 return 0; 274} 275 276/* 277 * Requires arche_pdata->platform_state_mutex to be held 278 */ 279static void 280arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) 281{ 282 unsigned long flags; 283 284 if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF) 285 return; 286 287 /* If in fw_flashing mode, then no need to repeate things again */ 288 if (arche_pdata->state != ARCHE_PLATFORM_STATE_FW_FLASHING) { 289 disable_irq(arche_pdata->wake_detect_irq); 290 291 spin_lock_irqsave(&arche_pdata->wake_lock, flags); 292 arche_platform_set_wake_detect_state(arche_pdata, 293 WD_STATE_IDLE); 294 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); 295 } 296 297 clk_disable_unprepare(arche_pdata->svc_ref_clk); 298 299 /* As part of exit, put APB back in reset state */ 300 svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi); 301 302 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); 303} 304 305static ssize_t state_store(struct device *dev, 306 struct device_attribute *attr, 307 const char *buf, size_t count) 308{ 309 struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev); 310 int ret = 0; 311 312 mutex_lock(&arche_pdata->platform_state_mutex); 313 314 if (sysfs_streq(buf, "off")) { 315 if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF) 316 goto exit; 317 318 /* If SVC goes down, bring down APB's as well */ 319 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); 320 321 arche_platform_poweroff_seq(arche_pdata); 322 323 } else if (sysfs_streq(buf, "active")) { 324 if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE) 325 goto exit; 326 327 /* First we want to make sure we power off everything 328 * and then activate back again 329 */ 330 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); 331 arche_platform_poweroff_seq(arche_pdata); 332 333 arche_platform_wd_irq_en(arche_pdata); 334 ret = arche_platform_coldboot_seq(arche_pdata); 335 if (ret) 336 goto exit; 337 338 } else if (sysfs_streq(buf, "standby")) { 339 if (arche_pdata->state == ARCHE_PLATFORM_STATE_STANDBY) 340 goto exit; 341 342 dev_warn(arche_pdata->dev, "standby state not supported\n"); 343 } else if (sysfs_streq(buf, "fw_flashing")) { 344 if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING) 345 goto exit; 346 347 /* 348 * Here we only control SVC. 349 * 350 * In case of FW_FLASHING mode we do not want to control 351 * APBs, as in case of V2, SPI bus is shared between both 352 * the APBs. So let user chose which APB he wants to flash. 353 */ 354 arche_platform_poweroff_seq(arche_pdata); 355 356 ret = arche_platform_fw_flashing_seq(arche_pdata); 357 if (ret) 358 goto exit; 359 } else { 360 dev_err(arche_pdata->dev, "unknown state\n"); 361 ret = -EINVAL; 362 } 363 364exit: 365 mutex_unlock(&arche_pdata->platform_state_mutex); 366 return ret ? ret : count; 367} 368 369static ssize_t state_show(struct device *dev, 370 struct device_attribute *attr, char *buf) 371{ 372 struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev); 373 374 switch (arche_pdata->state) { 375 case ARCHE_PLATFORM_STATE_OFF: 376 return sprintf(buf, "off\n"); 377 case ARCHE_PLATFORM_STATE_ACTIVE: 378 return sprintf(buf, "active\n"); 379 case ARCHE_PLATFORM_STATE_STANDBY: 380 return sprintf(buf, "standby\n"); 381 case ARCHE_PLATFORM_STATE_FW_FLASHING: 382 return sprintf(buf, "fw_flashing\n"); 383 default: 384 return sprintf(buf, "unknown state\n"); 385 } 386} 387 388static DEVICE_ATTR_RW(state); 389 390static int arche_platform_pm_notifier(struct notifier_block *notifier, 391 unsigned long pm_event, void *unused) 392{ 393 struct arche_platform_drvdata *arche_pdata = 394 container_of(notifier, struct arche_platform_drvdata, 395 pm_notifier); 396 int ret = NOTIFY_DONE; 397 398 mutex_lock(&arche_pdata->platform_state_mutex); 399 switch (pm_event) { 400 case PM_SUSPEND_PREPARE: 401 if (arche_pdata->state != ARCHE_PLATFORM_STATE_ACTIVE) { 402 ret = NOTIFY_STOP; 403 break; 404 } 405 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff); 406 arche_platform_poweroff_seq(arche_pdata); 407 break; 408 case PM_POST_SUSPEND: 409 if (arche_pdata->state != ARCHE_PLATFORM_STATE_OFF) 410 break; 411 412 arche_platform_wd_irq_en(arche_pdata); 413 arche_platform_coldboot_seq(arche_pdata); 414 break; 415 default: 416 break; 417 } 418 mutex_unlock(&arche_pdata->platform_state_mutex); 419 420 return ret; 421} 422 423static int arche_platform_probe(struct platform_device *pdev) 424{ 425 struct arche_platform_drvdata *arche_pdata; 426 struct device *dev = &pdev->dev; 427 struct device_node *np = dev->of_node; 428 int ret; 429 unsigned int flags; 430 431 arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), 432 GFP_KERNEL); 433 if (!arche_pdata) 434 return -ENOMEM; 435 436 /* setup svc reset gpio */ 437 arche_pdata->is_reset_act_hi = of_property_read_bool(np, 438 "svc,reset-active-high"); 439 if (arche_pdata->is_reset_act_hi) 440 flags = GPIOD_OUT_HIGH; 441 else 442 flags = GPIOD_OUT_LOW; 443 444 arche_pdata->svc_reset = devm_gpiod_get(dev, "svc,reset", flags); 445 if (IS_ERR(arche_pdata->svc_reset)) { 446 ret = PTR_ERR(arche_pdata->svc_reset); 447 dev_err(dev, "failed to request svc-reset GPIO: %d\n", ret); 448 return ret; 449 } 450 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); 451 452 arche_pdata->svc_sysboot = devm_gpiod_get(dev, "svc,sysboot", 453 GPIOD_OUT_LOW); 454 if (IS_ERR(arche_pdata->svc_sysboot)) { 455 ret = PTR_ERR(arche_pdata->svc_sysboot); 456 dev_err(dev, "failed to request sysboot0 GPIO: %d\n", ret); 457 return ret; 458 } 459 460 /* setup the clock request gpio first */ 461 arche_pdata->svc_refclk_req = devm_gpiod_get(dev, "svc,refclk-req", 462 GPIOD_IN); 463 if (IS_ERR(arche_pdata->svc_refclk_req)) { 464 ret = PTR_ERR(arche_pdata->svc_refclk_req); 465 dev_err(dev, "failed to request svc-clk-req GPIO: %d\n", ret); 466 return ret; 467 } 468 469 /* setup refclk2 to follow the pin */ 470 arche_pdata->svc_ref_clk = devm_clk_get(dev, "svc_ref_clk"); 471 if (IS_ERR(arche_pdata->svc_ref_clk)) { 472 ret = PTR_ERR(arche_pdata->svc_ref_clk); 473 dev_err(dev, "failed to get svc_ref_clk: %d\n", ret); 474 return ret; 475 } 476 477 platform_set_drvdata(pdev, arche_pdata); 478 479 arche_pdata->num_apbs = of_get_child_count(np); 480 dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs); 481 482 arche_pdata->wake_detect = devm_gpiod_get(dev, "svc,wake-detect", 483 GPIOD_IN); 484 if (IS_ERR(arche_pdata->wake_detect)) { 485 ret = PTR_ERR(arche_pdata->wake_detect); 486 dev_err(dev, "Failed requesting wake_detect GPIO: %d\n", ret); 487 return ret; 488 } 489 490 arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE); 491 492 arche_pdata->dev = &pdev->dev; 493 494 spin_lock_init(&arche_pdata->wake_lock); 495 mutex_init(&arche_pdata->platform_state_mutex); 496 arche_pdata->wake_detect_irq = 497 gpiod_to_irq(arche_pdata->wake_detect); 498 499 ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq, 500 arche_platform_wd_irq, 501 arche_platform_wd_irq_thread, 502 IRQF_TRIGGER_FALLING | 503 IRQF_TRIGGER_RISING | IRQF_ONESHOT, 504 dev_name(dev), arche_pdata); 505 if (ret) { 506 dev_err(dev, "failed to request wake detect IRQ %d\n", ret); 507 return ret; 508 } 509 disable_irq(arche_pdata->wake_detect_irq); 510 511 ret = device_create_file(dev, &dev_attr_state); 512 if (ret) { 513 dev_err(dev, "failed to create state file in sysfs\n"); 514 return ret; 515 } 516 517 ret = of_platform_populate(np, NULL, NULL, dev); 518 if (ret) { 519 dev_err(dev, "failed to populate child nodes %d\n", ret); 520 goto err_device_remove; 521 } 522 523 arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier; 524 ret = register_pm_notifier(&arche_pdata->pm_notifier); 525 526 if (ret) { 527 dev_err(dev, "failed to register pm notifier %d\n", ret); 528 goto err_device_remove; 529 } 530 531 /* Explicitly power off if requested */ 532 if (!of_property_read_bool(pdev->dev.of_node, "arche,init-off")) { 533 mutex_lock(&arche_pdata->platform_state_mutex); 534 ret = arche_platform_coldboot_seq(arche_pdata); 535 if (ret) { 536 dev_err(dev, "Failed to cold boot svc %d\n", ret); 537 goto err_coldboot; 538 } 539 arche_platform_wd_irq_en(arche_pdata); 540 mutex_unlock(&arche_pdata->platform_state_mutex); 541 } 542 543 dev_info(dev, "Device registered successfully\n"); 544 return 0; 545 546err_coldboot: 547 mutex_unlock(&arche_pdata->platform_state_mutex); 548err_device_remove: 549 device_remove_file(&pdev->dev, &dev_attr_state); 550 return ret; 551} 552 553static int arche_remove_child(struct device *dev, void *unused) 554{ 555 struct platform_device *pdev = to_platform_device(dev); 556 557 platform_device_unregister(pdev); 558 559 return 0; 560} 561 562static int arche_platform_remove(struct platform_device *pdev) 563{ 564 struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev); 565 566 unregister_pm_notifier(&arche_pdata->pm_notifier); 567 device_remove_file(&pdev->dev, &dev_attr_state); 568 device_for_each_child(&pdev->dev, NULL, arche_remove_child); 569 arche_platform_poweroff_seq(arche_pdata); 570 571 if (usb3613_hub_mode_ctrl(false)) 572 dev_warn(arche_pdata->dev, "failed to control hub device\n"); 573 /* TODO: Should we do anything more here ?? */ 574 return 0; 575} 576 577static __maybe_unused int arche_platform_suspend(struct device *dev) 578{ 579 /* 580 * If timing profile premits, we may shutdown bridge 581 * completely 582 * 583 * TODO: sequence ?? 584 * 585 * Also, need to make sure we meet precondition for unipro suspend 586 * Precondition: Definition ??? 587 */ 588 return 0; 589} 590 591static __maybe_unused int arche_platform_resume(struct device *dev) 592{ 593 /* 594 * At least for ES2 we have to meet the delay requirement between 595 * unipro switch and AP bridge init, depending on whether bridge is in 596 * OFF state or standby state. 597 * 598 * Based on whether bridge is in standby or OFF state we may have to 599 * assert multiple signals. Please refer to WDM spec, for more info. 600 * 601 */ 602 return 0; 603} 604 605static void arche_platform_shutdown(struct platform_device *pdev) 606{ 607 struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev); 608 609 arche_platform_poweroff_seq(arche_pdata); 610 611 usb3613_hub_mode_ctrl(false); 612} 613 614static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops, 615 arche_platform_suspend, 616 arche_platform_resume); 617 618static const struct of_device_id arche_platform_of_match[] = { 619 /* Use PID/VID of SVC device */ 620 { .compatible = "google,arche-platform", }, 621 { }, 622}; 623 624static const struct of_device_id arche_combined_id[] = { 625 /* Use PID/VID of SVC device */ 626 { .compatible = "google,arche-platform", }, 627 { .compatible = "usbffff,2", }, 628 { }, 629}; 630MODULE_DEVICE_TABLE(of, arche_combined_id); 631 632static struct platform_driver arche_platform_device_driver = { 633 .probe = arche_platform_probe, 634 .remove = arche_platform_remove, 635 .shutdown = arche_platform_shutdown, 636 .driver = { 637 .name = "arche-platform-ctrl", 638 .pm = &arche_platform_pm_ops, 639 .of_match_table = arche_platform_of_match, 640 } 641}; 642 643static int __init arche_init(void) 644{ 645 int retval; 646 647 retval = platform_driver_register(&arche_platform_device_driver); 648 if (retval) 649 return retval; 650 651 retval = arche_apb_init(); 652 if (retval) 653 platform_driver_unregister(&arche_platform_device_driver); 654 655 return retval; 656} 657module_init(arche_init); 658 659static void __exit arche_exit(void) 660{ 661 arche_apb_exit(); 662 platform_driver_unregister(&arche_platform_device_driver); 663} 664module_exit(arche_exit); 665 666MODULE_LICENSE("GPL v2"); 667MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath@linaro.org>"); 668MODULE_DESCRIPTION("Arche Platform Driver");