t7xx_pci.c (19897B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2021, MediaTek Inc. 4 * Copyright (c) 2021-2022, Intel Corporation. 5 * 6 * Authors: 7 * Haijun Liu <haijun.liu@mediatek.com> 8 * Ricardo Martinez <ricardo.martinez@linux.intel.com> 9 * Sreehari Kancharla <sreehari.kancharla@intel.com> 10 * 11 * Contributors: 12 * Amir Hanania <amir.hanania@intel.com> 13 * Andy Shevchenko <andriy.shevchenko@linux.intel.com> 14 * Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com> 15 * Eliot Lee <eliot.lee@intel.com> 16 * Moises Veleta <moises.veleta@intel.com> 17 */ 18 19#include <linux/atomic.h> 20#include <linux/bits.h> 21#include <linux/completion.h> 22#include <linux/device.h> 23#include <linux/dma-mapping.h> 24#include <linux/gfp.h> 25#include <linux/interrupt.h> 26#include <linux/io.h> 27#include <linux/iopoll.h> 28#include <linux/jiffies.h> 29#include <linux/list.h> 30#include <linux/module.h> 31#include <linux/mutex.h> 32#include <linux/pci.h> 33#include <linux/pm.h> 34#include <linux/pm_runtime.h> 35#include <linux/pm_wakeup.h> 36#include <linux/spinlock.h> 37 38#include "t7xx_mhccif.h" 39#include "t7xx_modem_ops.h" 40#include "t7xx_pci.h" 41#include "t7xx_pcie_mac.h" 42#include "t7xx_reg.h" 43#include "t7xx_state_monitor.h" 44 45#define T7XX_PCI_IREG_BASE 0 46#define T7XX_PCI_EREG_BASE 2 47 48#define PM_SLEEP_DIS_TIMEOUT_MS 20 49#define PM_ACK_TIMEOUT_MS 1500 50#define PM_AUTOSUSPEND_MS 20000 51#define PM_RESOURCE_POLL_TIMEOUT_US 10000 52#define PM_RESOURCE_POLL_STEP_US 100 53 54enum t7xx_pm_state { 55 MTK_PM_EXCEPTION, 56 MTK_PM_INIT, /* Device initialized, but handshake not completed */ 57 MTK_PM_SUSPENDED, 58 MTK_PM_RESUMED, 59}; 60 61static void t7xx_dev_set_sleep_capability(struct t7xx_pci_dev *t7xx_dev, bool enable) 62{ 63 void __iomem *ctrl_reg = IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_CTRL; 64 u32 value; 65 66 value = ioread32(ctrl_reg); 67 68 if (enable) 69 value &= ~T7XX_PCIE_MISC_MAC_SLEEP_DIS; 70 else 71 value |= T7XX_PCIE_MISC_MAC_SLEEP_DIS; 72 73 iowrite32(value, ctrl_reg); 74} 75 76static int t7xx_wait_pm_config(struct t7xx_pci_dev *t7xx_dev) 77{ 78 int ret, val; 79 80 ret = read_poll_timeout(ioread32, val, 81 (val & T7XX_PCIE_RESOURCE_STS_MSK) == T7XX_PCIE_RESOURCE_STS_MSK, 82 PM_RESOURCE_POLL_STEP_US, PM_RESOURCE_POLL_TIMEOUT_US, true, 83 IREG_BASE(t7xx_dev) + T7XX_PCIE_RESOURCE_STATUS); 84 if (ret == -ETIMEDOUT) 85 dev_err(&t7xx_dev->pdev->dev, "PM configuration timed out\n"); 86 87 return ret; 88} 89 90static int t7xx_pci_pm_init(struct t7xx_pci_dev *t7xx_dev) 91{ 92 struct pci_dev *pdev = t7xx_dev->pdev; 93 94 INIT_LIST_HEAD(&t7xx_dev->md_pm_entities); 95 mutex_init(&t7xx_dev->md_pm_entity_mtx); 96 spin_lock_init(&t7xx_dev->md_pm_lock); 97 init_completion(&t7xx_dev->sleep_lock_acquire); 98 init_completion(&t7xx_dev->pm_sr_ack); 99 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_INIT); 100 101 device_init_wakeup(&pdev->dev, true); 102 dev_pm_set_driver_flags(&pdev->dev, pdev->dev.power.driver_flags | 103 DPM_FLAG_NO_DIRECT_COMPLETE); 104 105 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR); 106 pm_runtime_set_autosuspend_delay(&pdev->dev, PM_AUTOSUSPEND_MS); 107 pm_runtime_use_autosuspend(&pdev->dev); 108 109 return t7xx_wait_pm_config(t7xx_dev); 110} 111 112void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev) 113{ 114 /* Enable the PCIe resource lock only after MD deep sleep is done */ 115 t7xx_mhccif_mask_clr(t7xx_dev, 116 D2H_INT_DS_LOCK_ACK | 117 D2H_INT_SUSPEND_ACK | 118 D2H_INT_RESUME_ACK | 119 D2H_INT_SUSPEND_ACK_AP | 120 D2H_INT_RESUME_ACK_AP); 121 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); 122 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED); 123 124 pm_runtime_put_noidle(&t7xx_dev->pdev->dev); 125} 126 127static int t7xx_pci_pm_reinit(struct t7xx_pci_dev *t7xx_dev) 128{ 129 /* The device is kept in FSM re-init flow 130 * so just roll back PM setting to the init setting. 131 */ 132 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_INIT); 133 134 pm_runtime_get_noresume(&t7xx_dev->pdev->dev); 135 136 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR); 137 return t7xx_wait_pm_config(t7xx_dev); 138} 139 140void t7xx_pci_pm_exp_detected(struct t7xx_pci_dev *t7xx_dev) 141{ 142 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR); 143 t7xx_wait_pm_config(t7xx_dev); 144 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_EXCEPTION); 145} 146 147int t7xx_pci_pm_entity_register(struct t7xx_pci_dev *t7xx_dev, struct md_pm_entity *pm_entity) 148{ 149 struct md_pm_entity *entity; 150 151 mutex_lock(&t7xx_dev->md_pm_entity_mtx); 152 list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) { 153 if (entity->id == pm_entity->id) { 154 mutex_unlock(&t7xx_dev->md_pm_entity_mtx); 155 return -EEXIST; 156 } 157 } 158 159 list_add_tail(&pm_entity->entity, &t7xx_dev->md_pm_entities); 160 mutex_unlock(&t7xx_dev->md_pm_entity_mtx); 161 return 0; 162} 163 164int t7xx_pci_pm_entity_unregister(struct t7xx_pci_dev *t7xx_dev, struct md_pm_entity *pm_entity) 165{ 166 struct md_pm_entity *entity, *tmp_entity; 167 168 mutex_lock(&t7xx_dev->md_pm_entity_mtx); 169 list_for_each_entry_safe(entity, tmp_entity, &t7xx_dev->md_pm_entities, entity) { 170 if (entity->id == pm_entity->id) { 171 list_del(&pm_entity->entity); 172 mutex_unlock(&t7xx_dev->md_pm_entity_mtx); 173 return 0; 174 } 175 } 176 177 mutex_unlock(&t7xx_dev->md_pm_entity_mtx); 178 179 return -ENXIO; 180} 181 182int t7xx_pci_sleep_disable_complete(struct t7xx_pci_dev *t7xx_dev) 183{ 184 struct device *dev = &t7xx_dev->pdev->dev; 185 int ret; 186 187 ret = wait_for_completion_timeout(&t7xx_dev->sleep_lock_acquire, 188 msecs_to_jiffies(PM_SLEEP_DIS_TIMEOUT_MS)); 189 if (!ret) 190 dev_err_ratelimited(dev, "Resource wait complete timed out\n"); 191 192 return ret; 193} 194 195/** 196 * t7xx_pci_disable_sleep() - Disable deep sleep capability. 197 * @t7xx_dev: MTK device. 198 * 199 * Lock the deep sleep capability, note that the device can still go into deep sleep 200 * state while device is in D0 state, from the host's point-of-view. 201 * 202 * If device is in deep sleep state, wake up the device and disable deep sleep capability. 203 */ 204void t7xx_pci_disable_sleep(struct t7xx_pci_dev *t7xx_dev) 205{ 206 unsigned long flags; 207 208 spin_lock_irqsave(&t7xx_dev->md_pm_lock, flags); 209 t7xx_dev->sleep_disable_count++; 210 if (atomic_read(&t7xx_dev->md_pm_state) < MTK_PM_RESUMED) 211 goto unlock_and_complete; 212 213 if (t7xx_dev->sleep_disable_count == 1) { 214 u32 status; 215 216 reinit_completion(&t7xx_dev->sleep_lock_acquire); 217 t7xx_dev_set_sleep_capability(t7xx_dev, false); 218 219 status = ioread32(IREG_BASE(t7xx_dev) + T7XX_PCIE_RESOURCE_STATUS); 220 if (status & T7XX_PCIE_RESOURCE_STS_MSK) 221 goto unlock_and_complete; 222 223 t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DS_LOCK); 224 } 225 spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags); 226 return; 227 228unlock_and_complete: 229 spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags); 230 complete_all(&t7xx_dev->sleep_lock_acquire); 231} 232 233/** 234 * t7xx_pci_enable_sleep() - Enable deep sleep capability. 235 * @t7xx_dev: MTK device. 236 * 237 * After enabling deep sleep, device can enter into deep sleep state. 238 */ 239void t7xx_pci_enable_sleep(struct t7xx_pci_dev *t7xx_dev) 240{ 241 unsigned long flags; 242 243 spin_lock_irqsave(&t7xx_dev->md_pm_lock, flags); 244 t7xx_dev->sleep_disable_count--; 245 if (atomic_read(&t7xx_dev->md_pm_state) < MTK_PM_RESUMED) 246 goto unlock; 247 248 if (t7xx_dev->sleep_disable_count == 0) 249 t7xx_dev_set_sleep_capability(t7xx_dev, true); 250 251unlock: 252 spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags); 253} 254 255static int t7xx_send_pm_request(struct t7xx_pci_dev *t7xx_dev, u32 request) 256{ 257 unsigned long wait_ret; 258 259 reinit_completion(&t7xx_dev->pm_sr_ack); 260 t7xx_mhccif_h2d_swint_trigger(t7xx_dev, request); 261 wait_ret = wait_for_completion_timeout(&t7xx_dev->pm_sr_ack, 262 msecs_to_jiffies(PM_ACK_TIMEOUT_MS)); 263 if (!wait_ret) 264 return -ETIMEDOUT; 265 266 return 0; 267} 268 269static int __t7xx_pci_pm_suspend(struct pci_dev *pdev) 270{ 271 enum t7xx_pm_id entity_id = PM_ENTITY_ID_INVALID; 272 struct t7xx_pci_dev *t7xx_dev; 273 struct md_pm_entity *entity; 274 int ret; 275 276 t7xx_dev = pci_get_drvdata(pdev); 277 if (atomic_read(&t7xx_dev->md_pm_state) <= MTK_PM_INIT) { 278 dev_err(&pdev->dev, "[PM] Exiting suspend, modem in invalid state\n"); 279 return -EFAULT; 280 } 281 282 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR); 283 ret = t7xx_wait_pm_config(t7xx_dev); 284 if (ret) { 285 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); 286 return ret; 287 } 288 289 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_SUSPENDED); 290 t7xx_pcie_mac_clear_int(t7xx_dev, SAP_RGU_INT); 291 t7xx_dev->rgu_pci_irq_en = false; 292 293 list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) { 294 if (!entity->suspend) 295 continue; 296 297 ret = entity->suspend(t7xx_dev, entity->entity_param); 298 if (ret) { 299 entity_id = entity->id; 300 dev_err(&pdev->dev, "[PM] Suspend error: %d, id: %d\n", ret, entity_id); 301 goto abort_suspend; 302 } 303 } 304 305 ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_SUSPEND_REQ); 306 if (ret) { 307 dev_err(&pdev->dev, "[PM] MD suspend error: %d\n", ret); 308 goto abort_suspend; 309 } 310 311 ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_SUSPEND_REQ_AP); 312 if (ret) { 313 t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ); 314 dev_err(&pdev->dev, "[PM] SAP suspend error: %d\n", ret); 315 goto abort_suspend; 316 } 317 318 list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) { 319 if (entity->suspend_late) 320 entity->suspend_late(t7xx_dev, entity->entity_param); 321 } 322 323 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); 324 return 0; 325 326abort_suspend: 327 list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) { 328 if (entity_id == entity->id) 329 break; 330 331 if (entity->resume) 332 entity->resume(t7xx_dev, entity->entity_param); 333 } 334 335 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); 336 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED); 337 t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT); 338 return ret; 339} 340 341static void t7xx_pcie_interrupt_reinit(struct t7xx_pci_dev *t7xx_dev) 342{ 343 t7xx_pcie_set_mac_msix_cfg(t7xx_dev, EXT_INT_NUM); 344 345 /* Disable interrupt first and let the IPs enable them */ 346 iowrite32(MSIX_MSK_SET_ALL, IREG_BASE(t7xx_dev) + IMASK_HOST_MSIX_CLR_GRP0_0); 347 348 /* Device disables PCIe interrupts during resume and 349 * following function will re-enable PCIe interrupts. 350 */ 351 t7xx_pcie_mac_interrupts_en(t7xx_dev); 352 t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT); 353} 354 355static int t7xx_pcie_reinit(struct t7xx_pci_dev *t7xx_dev, bool is_d3) 356{ 357 int ret; 358 359 ret = pcim_enable_device(t7xx_dev->pdev); 360 if (ret) 361 return ret; 362 363 t7xx_pcie_mac_atr_init(t7xx_dev); 364 t7xx_pcie_interrupt_reinit(t7xx_dev); 365 366 if (is_d3) { 367 t7xx_mhccif_init(t7xx_dev); 368 return t7xx_pci_pm_reinit(t7xx_dev); 369 } 370 371 return 0; 372} 373 374static int t7xx_send_fsm_command(struct t7xx_pci_dev *t7xx_dev, u32 event) 375{ 376 struct t7xx_fsm_ctl *fsm_ctl = t7xx_dev->md->fsm_ctl; 377 struct device *dev = &t7xx_dev->pdev->dev; 378 int ret = -EINVAL; 379 380 switch (event) { 381 case FSM_CMD_STOP: 382 ret = t7xx_fsm_append_cmd(fsm_ctl, FSM_CMD_STOP, FSM_CMD_FLAG_WAIT_FOR_COMPLETION); 383 break; 384 385 case FSM_CMD_START: 386 t7xx_pcie_mac_clear_int(t7xx_dev, SAP_RGU_INT); 387 t7xx_pcie_mac_clear_int_status(t7xx_dev, SAP_RGU_INT); 388 t7xx_dev->rgu_pci_irq_en = true; 389 t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT); 390 ret = t7xx_fsm_append_cmd(fsm_ctl, FSM_CMD_START, 0); 391 break; 392 393 default: 394 break; 395 } 396 397 if (ret) 398 dev_err(dev, "Failure handling FSM command %u, %d\n", event, ret); 399 400 return ret; 401} 402 403static int __t7xx_pci_pm_resume(struct pci_dev *pdev, bool state_check) 404{ 405 struct t7xx_pci_dev *t7xx_dev; 406 struct md_pm_entity *entity; 407 u32 prev_state; 408 int ret = 0; 409 410 t7xx_dev = pci_get_drvdata(pdev); 411 if (atomic_read(&t7xx_dev->md_pm_state) <= MTK_PM_INIT) { 412 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); 413 return 0; 414 } 415 416 t7xx_pcie_mac_interrupts_en(t7xx_dev); 417 prev_state = ioread32(IREG_BASE(t7xx_dev) + T7XX_PCIE_PM_RESUME_STATE); 418 419 if (state_check) { 420 /* For D3/L3 resume, the device could boot so quickly that the 421 * initial value of the dummy register might be overwritten. 422 * Identify new boots if the ATR source address register is not initialized. 423 */ 424 u32 atr_reg_val = ioread32(IREG_BASE(t7xx_dev) + 425 ATR_PCIE_WIN0_T0_ATR_PARAM_SRC_ADDR); 426 if (prev_state == PM_RESUME_REG_STATE_L3 || 427 (prev_state == PM_RESUME_REG_STATE_INIT && 428 atr_reg_val == ATR_SRC_ADDR_INVALID)) { 429 ret = t7xx_send_fsm_command(t7xx_dev, FSM_CMD_STOP); 430 if (ret) 431 return ret; 432 433 ret = t7xx_pcie_reinit(t7xx_dev, true); 434 if (ret) 435 return ret; 436 437 t7xx_clear_rgu_irq(t7xx_dev); 438 return t7xx_send_fsm_command(t7xx_dev, FSM_CMD_START); 439 } 440 441 if (prev_state == PM_RESUME_REG_STATE_EXP || 442 prev_state == PM_RESUME_REG_STATE_L2_EXP) { 443 if (prev_state == PM_RESUME_REG_STATE_L2_EXP) { 444 ret = t7xx_pcie_reinit(t7xx_dev, false); 445 if (ret) 446 return ret; 447 } 448 449 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_SUSPENDED); 450 t7xx_dev->rgu_pci_irq_en = true; 451 t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT); 452 453 t7xx_mhccif_mask_clr(t7xx_dev, 454 D2H_INT_EXCEPTION_INIT | 455 D2H_INT_EXCEPTION_INIT_DONE | 456 D2H_INT_EXCEPTION_CLEARQ_DONE | 457 D2H_INT_EXCEPTION_ALLQ_RESET | 458 D2H_INT_PORT_ENUM); 459 460 return ret; 461 } 462 463 if (prev_state == PM_RESUME_REG_STATE_L2) { 464 ret = t7xx_pcie_reinit(t7xx_dev, false); 465 if (ret) 466 return ret; 467 468 } else if (prev_state != PM_RESUME_REG_STATE_L1 && 469 prev_state != PM_RESUME_REG_STATE_INIT) { 470 ret = t7xx_send_fsm_command(t7xx_dev, FSM_CMD_STOP); 471 if (ret) 472 return ret; 473 474 t7xx_clear_rgu_irq(t7xx_dev); 475 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_SUSPENDED); 476 return 0; 477 } 478 } 479 480 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR); 481 t7xx_wait_pm_config(t7xx_dev); 482 483 list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) { 484 if (entity->resume_early) 485 entity->resume_early(t7xx_dev, entity->entity_param); 486 } 487 488 ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ); 489 if (ret) 490 dev_err(&pdev->dev, "[PM] MD resume error: %d\n", ret); 491 492 ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ_AP); 493 if (ret) 494 dev_err(&pdev->dev, "[PM] SAP resume error: %d\n", ret); 495 496 list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) { 497 if (entity->resume) { 498 ret = entity->resume(t7xx_dev, entity->entity_param); 499 if (ret) 500 dev_err(&pdev->dev, "[PM] Resume entry ID: %d error: %d\n", 501 entity->id, ret); 502 } 503 } 504 505 t7xx_dev->rgu_pci_irq_en = true; 506 t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT); 507 iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); 508 pm_runtime_mark_last_busy(&pdev->dev); 509 atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED); 510 511 return ret; 512} 513 514static int t7xx_pci_pm_resume_noirq(struct device *dev) 515{ 516 struct pci_dev *pdev = to_pci_dev(dev); 517 struct t7xx_pci_dev *t7xx_dev; 518 519 t7xx_dev = pci_get_drvdata(pdev); 520 t7xx_pcie_mac_interrupts_dis(t7xx_dev); 521 522 return 0; 523} 524 525static void t7xx_pci_shutdown(struct pci_dev *pdev) 526{ 527 __t7xx_pci_pm_suspend(pdev); 528} 529 530static int t7xx_pci_pm_suspend(struct device *dev) 531{ 532 return __t7xx_pci_pm_suspend(to_pci_dev(dev)); 533} 534 535static int t7xx_pci_pm_resume(struct device *dev) 536{ 537 return __t7xx_pci_pm_resume(to_pci_dev(dev), true); 538} 539 540static int t7xx_pci_pm_thaw(struct device *dev) 541{ 542 return __t7xx_pci_pm_resume(to_pci_dev(dev), false); 543} 544 545static int t7xx_pci_pm_runtime_suspend(struct device *dev) 546{ 547 return __t7xx_pci_pm_suspend(to_pci_dev(dev)); 548} 549 550static int t7xx_pci_pm_runtime_resume(struct device *dev) 551{ 552 return __t7xx_pci_pm_resume(to_pci_dev(dev), true); 553} 554 555static const struct dev_pm_ops t7xx_pci_pm_ops = { 556 .suspend = t7xx_pci_pm_suspend, 557 .resume = t7xx_pci_pm_resume, 558 .resume_noirq = t7xx_pci_pm_resume_noirq, 559 .freeze = t7xx_pci_pm_suspend, 560 .thaw = t7xx_pci_pm_thaw, 561 .poweroff = t7xx_pci_pm_suspend, 562 .restore = t7xx_pci_pm_resume, 563 .restore_noirq = t7xx_pci_pm_resume_noirq, 564 .runtime_suspend = t7xx_pci_pm_runtime_suspend, 565 .runtime_resume = t7xx_pci_pm_runtime_resume 566}; 567 568static int t7xx_request_irq(struct pci_dev *pdev) 569{ 570 struct t7xx_pci_dev *t7xx_dev; 571 int ret = 0, i; 572 573 t7xx_dev = pci_get_drvdata(pdev); 574 575 for (i = 0; i < EXT_INT_NUM; i++) { 576 const char *irq_descr; 577 int irq_vec; 578 579 if (!t7xx_dev->intr_handler[i]) 580 continue; 581 582 irq_descr = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_%d", 583 dev_driver_string(&pdev->dev), i); 584 if (!irq_descr) { 585 ret = -ENOMEM; 586 break; 587 } 588 589 irq_vec = pci_irq_vector(pdev, i); 590 ret = request_threaded_irq(irq_vec, t7xx_dev->intr_handler[i], 591 t7xx_dev->intr_thread[i], 0, irq_descr, 592 t7xx_dev->callback_param[i]); 593 if (ret) { 594 dev_err(&pdev->dev, "Failed to request IRQ: %d\n", ret); 595 break; 596 } 597 } 598 599 if (ret) { 600 while (i--) { 601 if (!t7xx_dev->intr_handler[i]) 602 continue; 603 604 free_irq(pci_irq_vector(pdev, i), t7xx_dev->callback_param[i]); 605 } 606 } 607 608 return ret; 609} 610 611static int t7xx_setup_msix(struct t7xx_pci_dev *t7xx_dev) 612{ 613 struct pci_dev *pdev = t7xx_dev->pdev; 614 int ret; 615 616 /* Only using 6 interrupts, but HW-design requires power-of-2 IRQs allocation */ 617 ret = pci_alloc_irq_vectors(pdev, EXT_INT_NUM, EXT_INT_NUM, PCI_IRQ_MSIX); 618 if (ret < 0) { 619 dev_err(&pdev->dev, "Failed to allocate MSI-X entry: %d\n", ret); 620 return ret; 621 } 622 623 ret = t7xx_request_irq(pdev); 624 if (ret) { 625 pci_free_irq_vectors(pdev); 626 return ret; 627 } 628 629 t7xx_pcie_set_mac_msix_cfg(t7xx_dev, EXT_INT_NUM); 630 return 0; 631} 632 633static int t7xx_interrupt_init(struct t7xx_pci_dev *t7xx_dev) 634{ 635 int ret, i; 636 637 if (!t7xx_dev->pdev->msix_cap) 638 return -EINVAL; 639 640 ret = t7xx_setup_msix(t7xx_dev); 641 if (ret) 642 return ret; 643 644 /* IPs enable interrupts when ready */ 645 for (i = 0; i < EXT_INT_NUM; i++) 646 t7xx_pcie_mac_set_int(t7xx_dev, i); 647 648 return 0; 649} 650 651static void t7xx_pci_infracfg_ao_calc(struct t7xx_pci_dev *t7xx_dev) 652{ 653 t7xx_dev->base_addr.infracfg_ao_base = t7xx_dev->base_addr.pcie_ext_reg_base + 654 INFRACFG_AO_DEV_CHIP - 655 t7xx_dev->base_addr.pcie_dev_reg_trsl_addr; 656} 657 658static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 659{ 660 struct t7xx_pci_dev *t7xx_dev; 661 int ret; 662 663 t7xx_dev = devm_kzalloc(&pdev->dev, sizeof(*t7xx_dev), GFP_KERNEL); 664 if (!t7xx_dev) 665 return -ENOMEM; 666 667 pci_set_drvdata(pdev, t7xx_dev); 668 t7xx_dev->pdev = pdev; 669 670 ret = pcim_enable_device(pdev); 671 if (ret) 672 return ret; 673 674 pci_set_master(pdev); 675 676 ret = pcim_iomap_regions(pdev, BIT(T7XX_PCI_IREG_BASE) | BIT(T7XX_PCI_EREG_BASE), 677 pci_name(pdev)); 678 if (ret) { 679 dev_err(&pdev->dev, "Could not request BARs: %d\n", ret); 680 return -ENOMEM; 681 } 682 683 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); 684 if (ret) { 685 dev_err(&pdev->dev, "Could not set PCI DMA mask: %d\n", ret); 686 return ret; 687 } 688 689 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); 690 if (ret) { 691 dev_err(&pdev->dev, "Could not set consistent PCI DMA mask: %d\n", ret); 692 return ret; 693 } 694 695 IREG_BASE(t7xx_dev) = pcim_iomap_table(pdev)[T7XX_PCI_IREG_BASE]; 696 t7xx_dev->base_addr.pcie_ext_reg_base = pcim_iomap_table(pdev)[T7XX_PCI_EREG_BASE]; 697 698 ret = t7xx_pci_pm_init(t7xx_dev); 699 if (ret) 700 return ret; 701 702 t7xx_pcie_mac_atr_init(t7xx_dev); 703 t7xx_pci_infracfg_ao_calc(t7xx_dev); 704 t7xx_mhccif_init(t7xx_dev); 705 706 ret = t7xx_md_init(t7xx_dev); 707 if (ret) 708 return ret; 709 710 t7xx_pcie_mac_interrupts_dis(t7xx_dev); 711 712 ret = t7xx_interrupt_init(t7xx_dev); 713 if (ret) { 714 t7xx_md_exit(t7xx_dev); 715 return ret; 716 } 717 718 t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT); 719 t7xx_pcie_mac_interrupts_en(t7xx_dev); 720 721 return 0; 722} 723 724static void t7xx_pci_remove(struct pci_dev *pdev) 725{ 726 struct t7xx_pci_dev *t7xx_dev; 727 int i; 728 729 t7xx_dev = pci_get_drvdata(pdev); 730 t7xx_md_exit(t7xx_dev); 731 732 for (i = 0; i < EXT_INT_NUM; i++) { 733 if (!t7xx_dev->intr_handler[i]) 734 continue; 735 736 free_irq(pci_irq_vector(pdev, i), t7xx_dev->callback_param[i]); 737 } 738 739 pci_free_irq_vectors(t7xx_dev->pdev); 740} 741 742static const struct pci_device_id t7xx_pci_table[] = { 743 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x4d75) }, 744 { } 745}; 746MODULE_DEVICE_TABLE(pci, t7xx_pci_table); 747 748static struct pci_driver t7xx_pci_driver = { 749 .name = "mtk_t7xx", 750 .id_table = t7xx_pci_table, 751 .probe = t7xx_pci_probe, 752 .remove = t7xx_pci_remove, 753 .driver.pm = &t7xx_pci_pm_ops, 754 .shutdown = t7xx_pci_shutdown, 755}; 756 757module_pci_driver(t7xx_pci_driver); 758 759MODULE_AUTHOR("MediaTek Inc"); 760MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver"); 761MODULE_LICENSE("GPL");