cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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");