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
54 enum 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
t7xx_dev_set_sleep_capability(struct t7xx_pci_dev * t7xx_dev,bool enable)61 static 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
t7xx_wait_pm_config(struct t7xx_pci_dev * t7xx_dev)76 static 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
t7xx_pci_pm_init(struct t7xx_pci_dev * t7xx_dev)90 static 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
t7xx_pci_pm_init_late(struct t7xx_pci_dev * t7xx_dev)112 void 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
t7xx_pci_pm_reinit(struct t7xx_pci_dev * t7xx_dev)127 static 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
t7xx_pci_pm_exp_detected(struct t7xx_pci_dev * t7xx_dev)140 void 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
t7xx_pci_pm_entity_register(struct t7xx_pci_dev * t7xx_dev,struct md_pm_entity * pm_entity)147 int 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
t7xx_pci_pm_entity_unregister(struct t7xx_pci_dev * t7xx_dev,struct md_pm_entity * pm_entity)164 int 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
t7xx_pci_sleep_disable_complete(struct t7xx_pci_dev * t7xx_dev)182 int 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 */
t7xx_pci_disable_sleep(struct t7xx_pci_dev * t7xx_dev)204 void 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
228 unlock_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 */
t7xx_pci_enable_sleep(struct t7xx_pci_dev * t7xx_dev)239 void 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
251 unlock:
252 spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags);
253 }
254
t7xx_send_pm_request(struct t7xx_pci_dev * t7xx_dev,u32 request)255 static 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
__t7xx_pci_pm_suspend(struct pci_dev * pdev)269 static 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
326 abort_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
t7xx_pcie_interrupt_reinit(struct t7xx_pci_dev * t7xx_dev)341 static 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
t7xx_pcie_reinit(struct t7xx_pci_dev * t7xx_dev,bool is_d3)355 static 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
t7xx_send_fsm_command(struct t7xx_pci_dev * t7xx_dev,u32 event)374 static 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
__t7xx_pci_pm_resume(struct pci_dev * pdev,bool state_check)403 static 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
t7xx_pci_pm_resume_noirq(struct device * dev)514 static 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
t7xx_pci_shutdown(struct pci_dev * pdev)525 static void t7xx_pci_shutdown(struct pci_dev *pdev)
526 {
527 __t7xx_pci_pm_suspend(pdev);
528 }
529
t7xx_pci_pm_suspend(struct device * dev)530 static int t7xx_pci_pm_suspend(struct device *dev)
531 {
532 return __t7xx_pci_pm_suspend(to_pci_dev(dev));
533 }
534
t7xx_pci_pm_resume(struct device * dev)535 static int t7xx_pci_pm_resume(struct device *dev)
536 {
537 return __t7xx_pci_pm_resume(to_pci_dev(dev), true);
538 }
539
t7xx_pci_pm_thaw(struct device * dev)540 static int t7xx_pci_pm_thaw(struct device *dev)
541 {
542 return __t7xx_pci_pm_resume(to_pci_dev(dev), false);
543 }
544
t7xx_pci_pm_runtime_suspend(struct device * dev)545 static int t7xx_pci_pm_runtime_suspend(struct device *dev)
546 {
547 return __t7xx_pci_pm_suspend(to_pci_dev(dev));
548 }
549
t7xx_pci_pm_runtime_resume(struct device * dev)550 static int t7xx_pci_pm_runtime_resume(struct device *dev)
551 {
552 return __t7xx_pci_pm_resume(to_pci_dev(dev), true);
553 }
554
555 static 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
t7xx_request_irq(struct pci_dev * pdev)568 static 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
t7xx_setup_msix(struct t7xx_pci_dev * t7xx_dev)611 static 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
t7xx_interrupt_init(struct t7xx_pci_dev * t7xx_dev)633 static 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
t7xx_pci_infracfg_ao_calc(struct t7xx_pci_dev * t7xx_dev)651 static 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
t7xx_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)658 static 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
t7xx_pci_remove(struct pci_dev * pdev)724 static 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
742 static const struct pci_device_id t7xx_pci_table[] = {
743 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x4d75) },
744 { }
745 };
746 MODULE_DEVICE_TABLE(pci, t7xx_pci_table);
747
748 static 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
757 module_pci_driver(t7xx_pci_driver);
758
759 MODULE_AUTHOR("MediaTek Inc");
760 MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver");
761 MODULE_LICENSE("GPL");
762