// 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_SETTING_REG 0x80
#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
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
#define PCIE_EN7581_RESET_TIME_MS 100
struct mtk_gen3_pcie;
/**
* struct mtk_gen3_pcie_pdata - differentiate between host generations
* @power_up: pcie power_up callback
* @phy_resets: phy reset lines SoC data.
*/
struct mtk_gen3_pcie_pdata {
int (*power_up)(struct mtk_gen3_pcie *pcie);
struct {
const char *id[MAX_NUM_PHY_RESETS];
int num_resets;
} phy_resets;
};
/**
* struct mtk_msi_set - MSI information for each set
* @base: IO mapped register base
* @msg_addr: MSI message address
* @saved_irq_state: IRQ enable state saved at suspend time
*/
struct mtk_msi_set {
void __iomem *base;
phys_addr_t msg_addr;
u32 saved_irq_state;
};
/**
* struct mtk_gen3_pcie - PCIe port information
* @dev: pointer to PCIe device
* @base: IO mapped register base
* @reg_base: physical register base
* @mac_reset: MAC reset control
* @phy_resets: PHY reset controllers
* @phy: PHY controller block
* @clks: PCIe clocks
* @num_clks: PCIe clocks count for this port
* @irq: PCIe controller interrupt number
* @saved_irq_state: IRQ enable state saved at suspend time
* @irq_lock: lock protecting IRQ register access
* @intx_domain: legacy INTx IRQ domain
* @msi_domain: MSI IRQ domain
* @msi_bottom_domain: MSI IRQ bottom domain
* @msi_sets: MSI sets information
* @lock: lock protecting IRQ bit map
* @msi_irq_in_use: bit map for assigned MSI IRQ
* @soc: pointer to SoC-dependent operations
*/
struct mtk_gen3_pcie {
struct device *dev;
void __iomem *base;
phys_addr_t reg_base;
struct reset_control *mac_reset;
struct reset_control_bulk_data phy_resets[MAX_NUM_PHY_RESETS];
struct phy *phy;
struct clk_bulk_data *clks;
int num_clks;
int irq;
u32 saved_irq_state;
raw_spinlock_t irq_lock;
struct irq_domain *intx_domain;
struct irq_domain *msi_domain;
struct irq_domain *msi_bottom_domain;
struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM];
struct mutex lock;
DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM);
const struct mtk_gen3_pcie_pdata *soc;
};
/* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */
static const char *const ltssm_str[] = {
"detect.quiet", /* 0x00 */
"detect.active", /* 0x01 */
"polling.active", /* 0x02 */
"polling.compliance",