// SPDX-License-Identifier: GPL-2.0
/*
* MediaTek PCIe host controller driver.
*
* Copyright (c) 2020 MediaTek Inc.
* Author: Jianjun Wang <jianjun.wang@mediatek.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of_device.h>
#include <linux/of_pci.h>
#include <linux/pci.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include "../pci.h"
#define PCIE_BASE_CFG_REG 0x14
#define PCIE_BASE_CFG_SPEED GENMASK(15, 8)
#define PCIE_SETTING_REG 0x80
#define PCIE_SETTING_LINK_WIDTH GENMASK(11, 8)
#define PCIE_SETTING_GEN_SUPPORT GENMASK(14, 12)
#define PCIE_PCI_IDS_1 0x9c
#define PCI_CLASS(class) (class << 8)
#define PCIE_RC_MODE BIT(0)
#define PCIE_EQ_PRESET_01_REG 0x100
#define PCIE_VAL_LN0_DOWNSTREAM GENMASK(6, 0)
#define PCIE_VAL_LN0_UPSTREAM GENMASK(14, 8)
#define PCIE_VAL_LN1_DOWNSTREAM GENMASK(22, 16)
#define PCIE_VAL_LN1_UPSTREAM GENMASK(30, 24)
#define PCIE_CFGNUM_REG 0x140
#define PCIE_CFG_DEVFN(devfn) ((devfn) & GENMASK(7, 0))
#define PCIE_CFG_BUS(bus) (((bus) << 8) & GENMASK(15, 8))
#define PCIE_CFG_BYTE_EN(bytes) (((bytes) << 16) & GENMASK(19, 16))
#define PCIE_CFG_FORCE_BYTE_EN BIT(20)
#define PCIE_CFG_OFFSET_ADDR 0x1000
#define PCIE_CFG_HEADER(bus, devfn) \
(PCIE_CFG_BUS(bus) | PCIE_CFG_DEVFN(devfn))
#define PCIE_RST_CTRL_REG 0x148
#define PCIE_MAC_RSTB BIT(0)
#define PCIE_PHY_RSTB BIT(1)
#define PCIE_BRG_RSTB BIT(2)
#define PCIE_PE_RSTB BIT(3)
#define PCIE_LTSSM_STATUS_REG 0x150
#define PCIE_LTSSM_STATE_MASK GENMASK(28, 24)
#define PCIE_LTSSM_STATE(val) ((val & PCIE_LTSSM_STATE_MASK) >> 24)
#define PCIE_LTSSM_STATE_L2_IDLE 0x14
#define PCIE_LINK_STATUS_REG 0x154
#define PCIE_PORT_LINKUP BIT(8)
#define PCIE_MSI_SET_NUM 8
#define PCIE_MSI_IRQS_PER_SET 32
#define PCIE_MSI_IRQS_NUM \
(PCIE_MSI_IRQS_PER_SET * PCIE_MSI_SET_NUM)
#define PCIE_INT_ENABLE_REG 0x180
#define PCIE_MSI_ENABLE GENMASK(PCIE_MSI_SET_NUM + 8 - 1, 8)
#define PCIE_MSI_SHIFT 8
#define PCIE_INTX_SHIFT 24
#define PCIE_INTX_ENABLE \
GENMASK(PCIE_INTX_SHIFT + PCI_NUM_INTX - 1, PCIE_INTX_SHIFT)
#define PCIE_INT_STATUS_REG 0x184
#define PCIE_MSI_SET_ENABLE_REG 0x190
#define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0)
#define PCIE_PIPE4_PIE8_REG 0x338
#define PCIE_K_FINETUNE_MAX GENMASK(5, 0)
#define PCIE_K_FINETUNE_ERR GENMASK(7, 6)
#define PCIE_K_PRESET_TO_USE GENMASK(18, 8)
#define PCIE_K_PHYPARAM_QUERY BIT(19)
#define PCIE_K_QUERY_TIMEOUT BIT(20)
#define PCIE_K_PRESET_TO_USE_16G GENMASK(31, 21)
#define PCIE_MSI_SET_BASE_REG 0xc00
#define PCIE_MSI_SET_OFFSET 0x10
#define PCIE_MSI_SET_STATUS_OFFSET 0x04
#define PCIE_MSI_SET_ENABLE_OFFSET 0x08
#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80
#define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04
#define PCIE_ICMD_PM_REG 0x198
#define PCIE_TURN_OFF_LINK BIT(4)
#define PCIE_MISC_CTRL_REG 0x348
#define PCIE_DISABLE_DVFSRC_VLT_REQ BIT(1)
#define PCIE_TRANS_TABLE_BASE_REG 0x800
#define PCIE_ATR_SRC_ADDR_MSB_OFFSET 0x4
#define PCIE_ATR_TRSL_ADDR_LSB_OFFSET 0x8
#define PCIE_ATR_TRSL_ADDR_MSB_OFFSET 0xc
#define PCIE_ATR_TRSL_PARAM_OFFSET 0x10
#define PCIE_ATR_TLB_SET_OFFSET 0x20
#define PCIE_MAX_TRANS_TABLES 8
#define PCIE_ATR_EN BIT(0)
#define PCIE_ATR_SIZE(size) \
(((((size) - 1) << 1) & GENMASK(6, 1)) | PCIE_ATR_EN)
#define PCIE_ATR_ID(id) ((id) & GENMASK(3, 0))
#define PCIE_ATR_TYPE_MEM PCIE_ATR_ID(0)
#define PCIE_ATR_TYPE_IO PCIE_ATR_ID(1)
#define PCIE_ATR_TLP_TYPE(type) (((type) << 16) & GENMASK(18, 16))
#define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0)
#define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2)
#define MAX_NUM_PHY_RESETS 3
#define PCIE_MTK_RESET_TIME_US 10
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
#define PCIE_EN7581_RESET_TIME_MS 100
struct mtk_gen3_pcie;
#define PCIE_CONF_LINK2_CTL_STS (PCIE_CFG_OFFSET_ADDR + 0xb0)
#define PCIE_CONF_LINK2_LCR2_LINK_SPEED GENMASK(3, 0)
enum mtk_gen3_pcie_flags {
SKIP_PCIE_RSTB = BIT(0), /* Skip PERST# assertion during device
* probing or suspend/resume phase to
* avoid hw bugs/issues.
*/
};
/**
* struct mtk_gen3_pcie_pdata - differentiate between host generations
* @power_up: pcie power_up callback
* @phy_resets: phy reset lines SoC data.
* @flags: pcie device flags.
*/
struct mtk_gen3_pcie_pdata {
int (*power_up)(struct mtk_gen3_pcie *pcie);
struct {
const char *id[