msm: ep_pcie: add PCIe endpoint driver snapshot

Snapshot of PCIe endpoint driver as of msm-4.14.

'commit <adeff59> (""drivers: clk: msm:
fix compilation for non DEBUG_FS build"")'.

The following changes were done:
-Replace msm_bus driver with interconnect framework.
-Remove iommu deprecated API's.
-Fix checkpatch warnings on usage of module param.
-Fix several checkpatch warnings.

Change-Id: I04ee8f5d5802af0aa0cdd607a79c91e3eca7f194
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
This commit is contained in:
Siddartha Mohanadoss 2020-07-29 15:40:55 -07:00
commit 77bd2d1044
10 changed files with 5461 additions and 0 deletions

View file

@ -42,6 +42,27 @@ config SPS_SUPPORT_NDP_BAM
to do the actual data transfer themselves, instead of the
BAM.
config EP_PCIE
bool "PCIe Endpoint mode support"
select GENERIC_ALLOCATOR
help
PCIe controller is in endpoint mode.
It supports the APIs to clients as a service layer, and allows
clients to enable/disable PCIe link, configure the address
mapping for the access to host memory, trigger wake interrupt
on host side to wake up host, and trigger MSI to host side.
config EP_PCIE_HW
bool "PCIe Endpoint HW driver"
depends on EP_PCIE
help
PCIe endpoint HW specific implementation.
It supports:
1. link training with Root Complex.
2. Address mapping.
3. Sideband signaling.
4. Power management.
config IPA3
tristate "IPA3 support"
depends on NET

View file

@ -11,3 +11,4 @@ obj-$(CONFIG_USB_BAM) += usb_bam.o
obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
obj-$(CONFIG_SPS) += sps/
obj-$(CONFIG_MSM_11AD) += msm_11ad/
obj-$(CONFIG_EP_PCIE) += ep_pcie/

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the PCIE EP specific device drivers.
#
obj-$(CONFIG_EP_PCIE) += ep_pcie.o
obj-$(CONFIG_EP_PCIE_HW) += ep_pcie_core.o ep_pcie_phy.o ep_pcie_dbg.o

View file

@ -0,0 +1,207 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015, 2017-2020, The Linux Foundation. All rights reserved.*/
/*
* MSM PCIe endpoint service layer.
*/
#include <linux/types.h>
#include <linux/list.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include "ep_pcie_com.h"
LIST_HEAD(head);
int ep_pcie_register_drv(struct ep_pcie_hw *handle)
{
struct ep_pcie_hw *present;
bool new = true;
if (WARN_ON(!handle))
return -EINVAL;
list_for_each_entry(present, &head, node) {
if (present->device_id == handle->device_id) {
new = false;
break;
}
}
if (new) {
list_add(&handle->node, &head);
pr_debug("ep_pcie:%s: register a new driver for device 0x%x\n",
__func__, handle->device_id);
return 0;
}
pr_debug(
"ep_pcie:%s: driver to register for device 0x%x has already existed\n",
__func__, handle->device_id);
return -EEXIST;
}
EXPORT_SYMBOL(ep_pcie_register_drv);
int ep_pcie_deregister_drv(struct ep_pcie_hw *handle)
{
struct ep_pcie_hw *present;
bool found = false;
if (WARN_ON(!handle))
return -EINVAL;
list_for_each_entry(present, &head, node) {
if (present->device_id == handle->device_id) {
found = true;
list_del(&handle->node);
break;
}
}
if (found) {
pr_debug("ep_pcie:%s: deregistered driver for device 0x%x\n",
__func__, handle->device_id);
return 0;
}
pr_err("ep_pcie:%s: driver for device 0x%x does not exist\n",
__func__, handle->device_id);
return -EEXIST;
}
EXPORT_SYMBOL(ep_pcie_deregister_drv);
struct ep_pcie_hw *ep_pcie_get_phandle(u32 id)
{
struct ep_pcie_hw *present;
list_for_each_entry(present, &head, node) {
if (present->device_id == id) {
pr_debug("ep_pcie:%s: found driver for device 0x%x\n",
__func__, id);
return present;
}
}
pr_debug("ep_pcie:%s: driver for device 0x%x does not exist\n",
__func__, id);
return NULL;
}
EXPORT_SYMBOL(ep_pcie_get_phandle);
int ep_pcie_configure_inactivity_timer(struct ep_pcie_hw *phandle,
struct ep_pcie_inactivity *param)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->configure_inactivity_timer(param);
}
EXPORT_SYMBOL(ep_pcie_configure_inactivity_timer);
int ep_pcie_register_event(struct ep_pcie_hw *phandle,
struct ep_pcie_register_event *reg)
{
if (phandle)
return phandle->register_event(reg);
return ep_pcie_core_register_event(reg);
}
EXPORT_SYMBOL(ep_pcie_register_event);
int ep_pcie_deregister_event(struct ep_pcie_hw *phandle)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->deregister_event();
}
EXPORT_SYMBOL(ep_pcie_deregister_event);
enum ep_pcie_link_status ep_pcie_get_linkstatus(struct ep_pcie_hw *phandle)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->get_linkstatus();
}
EXPORT_SYMBOL(ep_pcie_get_linkstatus);
int ep_pcie_config_outbound_iatu(struct ep_pcie_hw *phandle,
struct ep_pcie_iatu entries[],
u32 num_entries)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->config_outbound_iatu(entries, num_entries);
}
EXPORT_SYMBOL(ep_pcie_config_outbound_iatu);
int ep_pcie_get_msi_config(struct ep_pcie_hw *phandle,
struct ep_pcie_msi_config *cfg)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->get_msi_config(cfg);
}
EXPORT_SYMBOL(ep_pcie_get_msi_config);
int ep_pcie_trigger_msi(struct ep_pcie_hw *phandle, u32 idx)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->trigger_msi(idx);
}
EXPORT_SYMBOL(ep_pcie_trigger_msi);
int ep_pcie_wakeup_host(struct ep_pcie_hw *phandle,
enum ep_pcie_event event)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->wakeup_host(event);
}
EXPORT_SYMBOL(ep_pcie_wakeup_host);
int ep_pcie_config_db_routing(struct ep_pcie_hw *phandle,
struct ep_pcie_db_config chdb_cfg,
struct ep_pcie_db_config erdb_cfg)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->config_db_routing(chdb_cfg, erdb_cfg);
}
EXPORT_SYMBOL(ep_pcie_config_db_routing);
int ep_pcie_enable_endpoint(struct ep_pcie_hw *phandle,
enum ep_pcie_options opt)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->enable_endpoint(opt);
}
EXPORT_SYMBOL(ep_pcie_enable_endpoint);
int ep_pcie_disable_endpoint(struct ep_pcie_hw *phandle)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->disable_endpoint();
}
EXPORT_SYMBOL(ep_pcie_disable_endpoint);
int ep_pcie_mask_irq_event(struct ep_pcie_hw *phandle,
enum ep_pcie_irq_event event,
bool enable)
{
if (WARN_ON(!phandle))
return -EINVAL;
return phandle->mask_irq_event(event, enable);
}
EXPORT_SYMBOL(ep_pcie_mask_irq_event);

View file

@ -0,0 +1,451 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.*/
#ifndef __EP_PCIE_COM_H
#define __EP_PCIE_COM_H
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/ipc_logging.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/msm_ep_pcie.h>
#include <linux/iommu.h>
#define PCIE20_PARF_SYS_CTRL 0x00
#define PCIE20_PARF_DB_CTRL 0x10
#define PCIE20_PARF_PM_CTRL 0x20
#define PCIE20_PARF_PM_STTS 0x24
#define PCIE20_PARF_PHY_CTRL 0x40
#define PCIE20_PARF_PHY_REFCLK 0x4C
#define PCIE20_PARF_CONFIG_BITS 0x50
#define PCIE20_PARF_TEST_BUS 0xE4
#define PCIE20_PARF_MHI_BASE_ADDR_LOWER 0x178
#define PCIE20_PARF_MHI_BASE_ADDR_UPPER 0x17c
#define PCIE20_PARF_L1SUB_AHB_CLK_MAX_TIMER 0x180
#define PCIE20_PARF_L1SUB_AHB_CLK_MAX_TIMER_RESET_MASK 0x8000000
#define PCIE20_PARF_MSI_GEN 0x188
#define PCIE20_PARF_DEBUG_INT_EN 0x190
#define PCIE20_PARF_DEBUG_INT_EN_L1SUB_TIMEOUT_BIT_MASK BIT(0)
#define PCIE20_PARF_MHI_IPA_DBS 0x198
#define PCIE20_PARF_MHI_IPA_CDB_TARGET_LOWER 0x19C
#define PCIE20_PARF_MHI_IPA_EDB_TARGET_LOWER 0x1A0
#define PCIE20_PARF_AXI_MSTR_RD_HALT_NO_WRITES 0x1A4
#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x1A8
#define PCIE20_PARF_Q2A_FLUSH 0x1AC
#define PCIE20_PARF_LTSSM 0x1B0
#define PCIE20_PARF_CFG_BITS 0x210
#define PCIE20_PARF_LTR_MSI_EXIT_L1SS 0x214
#define PCIE20_PARF_INT_ALL_STATUS 0x224
#define PCIE20_PARF_INT_ALL_CLEAR 0x228
#define PCIE20_PARF_INT_ALL_MASK 0x22C
#define PCIE20_PARF_CLKREQ_OVERRIDE 0x2B0
#define PCIE20_PARF_CLKREQ_IN_OVERRIDE_STS BIT(5)
#define PCIE20_PARF_CLKREQ_OE_OVERRIDE_STS BIT(4)
#define PCIE20_PARF_CLKREQ_IN_OVERRIDE_VAL BIT(3)
#define PCIE20_PARF_CLKREQ_OE_OVERRIDE_VAL BIT(2)
#define PCIE20_PARF_CLKREQ_IN_OVERRIDE_ENABLE BIT(1)
#define PCIE20_PARF_CLKREQ_OE_OVERRIDE_ENABLE BIT(0)
#define PCIE20_PARF_SLV_ADDR_MSB_CTRL 0x2C0
#define PCIE20_PARF_DBI_BASE_ADDR 0x350
#define PCIE20_PARF_DBI_BASE_ADDR_HI 0x354
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x358
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE_HI 0x35C
#define PCIE20_PARF_L1SS_SLEEP_MODE_HANDLER_STATUS 0x4D0
#define PCIE20_PARF_L1SS_SLEEP_MHI_FWD_DISABLE BIT(5)
#define PCIE20_PARF_L1SS_SLEEP_MHI_FWD_ENABLE BIT(4)
#define PCIE20_PARF_L1SS_SLEEP_MODE_HANDLER_CONFIG 0x4D4
#define PCIE20_PARF_ATU_BASE_ADDR 0x634
#define PCIE20_PARF_ATU_BASE_ADDR_HI 0x638
#define PCIE20_PARF_SRIS_MODE 0x644
#define PCIE20_PARF_BUS_DISCONNECT_CTRL 0x648
#define PCIE20_PARF_BUS_DISCONNECT_STATUS 0x64c
#define PCIE20_PARF_BDF_TO_SID_CFG 0x2c00
#define PCIE20_PARF_DEVICE_TYPE 0x1000
#define PCIE20_PARF_EDMA_BASE_ADDR 0x64C
#define PCIE20_PARF_EDMA_BASE_ADDR_HI 0x650
#define PCIE20_ELBI_VERSION 0x00
#define PCIE20_ELBI_SYS_CTRL 0x04
#define PCIE20_ELBI_SYS_STTS 0x08
#define PCIE20_ELBI_CS2_ENABLE 0xA4
#define PCIE20_DEVICE_ID_VENDOR_ID 0x00
#define PCIE20_MASK_DEVICE_ID GENMASK(31, 16)
#define PCIE20_MASK_VENDOR_ID GENMASK(15, 0)
#define PCIE20_COMMAND_STATUS 0x04
#define PCIE20_CLASS_CODE_REVISION_ID 0x08
#define PCIE20_BIST_HDR_TYPE 0x0C
#define PCIE20_BAR0 0x10
#define PCIE20_SUBSYSTEM 0x2c
#define PCIE20_CAP_ID_NXT_PTR 0x40
#define PCIE20_CON_STATUS 0x44
#define PCIE20_MSI_CAP_ID_NEXT_CTRL 0x50
#define PCIE20_MSI_LOWER 0x54
#define PCIE20_MSI_UPPER 0x58
#define PCIE20_MSI_DATA 0x5C
#define PCIE20_MSI_MASK 0x60
#define PCIE20_DEVICE_CAPABILITIES 0x74
#define PCIE20_MASK_EP_L1_ACCPT_LATENCY 0xE00
#define PCIE20_MASK_EP_L0S_ACCPT_LATENCY 0x1C0
#define PCIE20_LINK_CAPABILITIES 0x7C
#define PCIE20_MASK_CLOCK_POWER_MAN 0x40000
#define PCIE20_MASK_L1_EXIT_LATENCY 0x38000
#define PCIE20_MASK_L0S_EXIT_LATENCY 0x7000
#define PCIE20_CAP_LINKCTRLSTATUS 0x80
#define PCIE20_DEVICE_CONTROL2_STATUS2 0x98
#define PCIE20_LINK_CONTROL2_LINK_STATUS2 0xA0
#define PCIE20_L1SUB_CAPABILITY 0x154
#define PCIE20_L1SUB_CONTROL1 0x158
#define PCIE20_BUS_DISCONNECT_STATUS 0x68c
#define PCIE20_ACK_F_ASPM_CTRL_REG 0x70C
#define PCIE20_MASK_ACK_N_FTS 0xff00
#define PCIE20_MISC_CONTROL_1 0x8BC
#define PCIE20_PLR_IATU_VIEWPORT 0x900
#define PCIE20_PLR_IATU_CTRL1 0x904
#define PCIE20_PLR_IATU_CTRL2 0x908
#define PCIE20_PLR_IATU_LBAR 0x90C
#define PCIE20_PLR_IATU_UBAR 0x910
#define PCIE20_PLR_IATU_LAR 0x914
#define PCIE20_PLR_IATU_LTAR 0x918
#define PCIE20_PLR_IATU_UTAR 0x91c
#define PCIE20_IATU_BASE(n) (n * 0x200)
#define PCIE20_IATU_O_CTRL1(n) (PCIE20_IATU_BASE(n) + 0x00)
#define PCIE20_IATU_O_CTRL2(n) (PCIE20_IATU_BASE(n) + 0x04)
#define PCIE20_IATU_O_LBAR(n) (PCIE20_IATU_BASE(n) + 0x08)
#define PCIE20_IATU_O_UBAR(n) (PCIE20_IATU_BASE(n) + 0x0c)
#define PCIE20_IATU_O_LAR(n) (PCIE20_IATU_BASE(n) + 0x10)
#define PCIE20_IATU_O_LTAR(n) (PCIE20_IATU_BASE(n) + 0x14)
#define PCIE20_IATU_O_UTAR(n) (PCIE20_IATU_BASE(n) + 0x18)
#define PCIE20_IATU_I_CTRL1(n) (PCIE20_IATU_BASE(n) + 0x100)
#define PCIE20_IATU_I_CTRL2(n) (PCIE20_IATU_BASE(n) + 0x104)
#define PCIE20_IATU_I_LBAR(n) (PCIE20_IATU_BASE(n) + 0x108)
#define PCIE20_IATU_I_UBAR(n) (PCIE20_IATU_BASE(n) + 0x10c)
#define PCIE20_IATU_I_LAR(n) (PCIE20_IATU_BASE(n) + 0x110)
#define PCIE20_IATU_I_LTAR(n) (PCIE20_IATU_BASE(n) + 0x114)
#define PCIE20_IATU_I_UTAR(n) (PCIE20_IATU_BASE(n) + 0x118)
#define PCIE20_MHICFG 0x110
#define PCIE20_BHI_EXECENV 0x228
#define PCIE20_MHIVER 0x108
#define PCIE20_MHICTRL 0x138
#define PCIE20_MHISTATUS 0x148
#define PCIE20_BHI_VERSION_LOWER 0x200
#define PCIE20_BHI_VERSION_UPPER 0x204
#define PCIE20_BHI_INTVEC 0x220
#define PCIE20_AUX_CLK_FREQ_REG 0xB40
#define PCIE20_GEN3_RELATED_OFF 0x890
#define PERST_TIMEOUT_US_MIN 1000
#define PERST_TIMEOUT_US_MAX 1000
#define PERST_CHECK_MAX_COUNT 30000
#define LINK_UP_TIMEOUT_US_MIN 1000
#define LINK_UP_TIMEOUT_US_MAX 1000
#define LINK_UP_CHECK_MAX_COUNT 30000
#define BME_TIMEOUT_US_MIN 1000
#define BME_TIMEOUT_US_MAX 1000
#define BME_CHECK_MAX_COUNT 100000
#define PHY_STABILIZATION_DELAY_US_MIN 1000
#define PHY_STABILIZATION_DELAY_US_MAX 1000
#define REFCLK_STABILIZATION_DELAY_US_MIN 1000
#define REFCLK_STABILIZATION_DELAY_US_MAX 1000
#define PHY_READY_TIMEOUT_COUNT 30000
#define MSI_EXIT_L1SS_WAIT 10
#define MSI_EXIT_L1SS_WAIT_MAX_COUNT 100
#define XMLH_LINK_UP 0x400
#define PARF_XMLH_LINK_UP 0x40000000
#define MAX_PROP_SIZE 32
#define MAX_MSG_LEN 80
#define MAX_NAME_LEN 80
#define MAX_IATU_ENTRY_NUM 2
#define EP_PCIE_LOG_PAGES 50
#define EP_PCIE_MAX_VREG 3
#define EP_PCIE_MAX_CLK 7
#define EP_PCIE_MAX_PIPE_CLK 1
#define EP_PCIE_MAX_RESET 2
#define EP_PCIE_ERROR -30655
#define EP_PCIE_LINK_DOWN 0xFFFFFFFF
#define EP_PCIE_OATU_INDEX_MSI 1
#define EP_PCIE_OATU_INDEX_CTRL 2
#define EP_PCIE_OATU_INDEX_DATA 3
#define EP_PCIE_OATU_UPPER 0x100
#define EP_PCIE_GEN_DBG(x...) do { \
if (ep_pcie_get_debug_mask()) \
pr_alert(x); \
else \
pr_debug(x); \
} while (0)
#define EP_PCIE_DBG(dev, fmt, arg...) do { \
ipc_log_string((dev)->ipc_log_ful, "%s: " fmt, __func__, arg); \
if (ep_pcie_get_debug_mask()) \
pr_alert("%s: " fmt, __func__, arg); \
} while (0)
#define EP_PCIE_DBG2(dev, fmt, arg...) do { \
ipc_log_string((dev)->ipc_log_sel, \
"DBG1:%s: " fmt, __func__, arg); \
ipc_log_string((dev)->ipc_log_ful, \
"DBG2:%s: " fmt, __func__, arg); \
if (ep_pcie_get_debug_mask()) \
pr_alert("%s: " fmt, __func__, arg); \
} while (0)
#define EP_PCIE_DBG_FS(fmt, arg...) pr_alert("%s: " fmt, __func__, arg)
#define EP_PCIE_DUMP(dev, fmt, arg...) do { \
ipc_log_string((dev)->ipc_log_dump, \
"DUMP:%s: " fmt, __func__, arg); \
if (ep_pcie_get_debug_mask()) \
pr_alert("%s: " fmt, __func__, arg); \
} while (0)
#define EP_PCIE_INFO(dev, fmt, arg...) do { \
ipc_log_string((dev)->ipc_log_sel, \
"INFO:%s: " fmt, __func__, arg); \
ipc_log_string((dev)->ipc_log_ful, "%s: " fmt, __func__, arg); \
pr_info("%s: " fmt, __func__, arg); \
} while (0)
#define EP_PCIE_ERR(dev, fmt, arg...) do { \
ipc_log_string((dev)->ipc_log_sel, \
"ERR:%s: " fmt, __func__, arg); \
ipc_log_string((dev)->ipc_log_ful, "%s: " fmt, __func__, arg); \
pr_err("%s: " fmt, __func__, arg); \
} while (0)
enum ep_pcie_res {
EP_PCIE_RES_PARF,
EP_PCIE_RES_PHY,
EP_PCIE_RES_MMIO,
EP_PCIE_RES_MSI,
EP_PCIE_RES_DM_CORE,
EP_PCIE_RES_ELBI,
EP_PCIE_RES_IATU,
EP_PCIE_RES_EDMA,
EP_PCIE_RES_TCSR_PERST,
EP_PCIE_MAX_RES,
};
enum ep_pcie_irq {
EP_PCIE_INT_PM_TURNOFF,
EP_PCIE_INT_DSTATE_CHANGE,
EP_PCIE_INT_L1SUB_TIMEOUT,
EP_PCIE_INT_LINK_UP,
EP_PCIE_INT_LINK_DOWN,
EP_PCIE_INT_BRIDGE_FLUSH_N,
EP_PCIE_INT_BME,
EP_PCIE_INT_GLOBAL,
EP_PCIE_MAX_IRQ,
};
enum ep_pcie_gpio {
EP_PCIE_GPIO_PERST,
EP_PCIE_GPIO_WAKE,
EP_PCIE_GPIO_CLKREQ,
EP_PCIE_GPIO_MDM2AP,
EP_PCIE_MAX_GPIO,
};
struct ep_pcie_gpio_info_t {
char *name;
u32 num;
bool out;
u32 on;
u32 init;
};
struct ep_pcie_vreg_info_t {
struct regulator *hdl;
char *name;
u32 max_v;
u32 min_v;
u32 opt_mode;
bool required;
};
struct ep_pcie_clk_info_t {
struct clk *hdl;
char *name;
u32 freq;
bool required;
};
struct ep_pcie_reset_info_t {
struct reset_control *hdl;
char *name;
bool required;
};
struct ep_pcie_res_info_t {
char *name;
struct resource *resource;
void __iomem *base;
};
struct ep_pcie_irq_info_t {
char *name;
u32 num;
};
/* phy info structure */
struct ep_pcie_phy_info_t {
u32 offset;
u32 val;
u32 delay;
u32 direction;
};
/* pcie endpoint device structure */
struct ep_pcie_dev_t {
struct platform_device *pdev;
struct regulator *gdsc;
struct ep_pcie_vreg_info_t vreg[EP_PCIE_MAX_VREG];
struct ep_pcie_gpio_info_t gpio[EP_PCIE_MAX_GPIO];
struct ep_pcie_clk_info_t clk[EP_PCIE_MAX_CLK];
struct ep_pcie_clk_info_t pipeclk[EP_PCIE_MAX_PIPE_CLK];
struct ep_pcie_reset_info_t reset[EP_PCIE_MAX_RESET];
struct ep_pcie_irq_info_t irq[EP_PCIE_MAX_IRQ];
struct ep_pcie_res_info_t res[EP_PCIE_MAX_RES];
u32 mmio_res_size;
void __iomem *parf;
void __iomem *phy;
void __iomem *mmio;
void __iomem *msi;
void __iomem *dm_core;
void __iomem *edma;
void __iomem *elbi;
void __iomem *iatu;
void __iomem *tcsr_perst_en;
struct msm_bus_scale_pdata *bus_scale_table;
struct icc_path *icc_path;
u16 vendor_id;
u16 device_id;
u32 subsystem_id;
u32 link_speed;
bool active_config;
bool aggregated_irq;
bool mhi_a7_irq;
bool pcie_edma;
bool tcsr_not_supported;
bool m2_autonomous;
bool mhi_soc_reset_en;
u32 dbi_base_reg;
u32 slv_space_reg;
u32 phy_status_reg;
u32 phy_status_bit_mask_bit;
u32 phy_init_len;
u32 mhi_soc_reset_offset;
struct ep_pcie_phy_info_t *phy_init;
bool perst_enum;
u32 rev;
u32 phy_rev;
void *ipc_log_sel;
void *ipc_log_ful;
void *ipc_log_dump;
struct mutex setup_mtx;
struct mutex ext_mtx;
spinlock_t ext_lock;
unsigned long ext_save_flags;
spinlock_t isr_lock;
unsigned long isr_save_flags;
ulong linkdown_counter;
ulong linkup_counter;
ulong bme_counter;
ulong pm_to_counter;
ulong d0_counter;
ulong d3_counter;
ulong perst_ast_counter;
ulong perst_deast_counter;
ulong wake_counter;
ulong msi_counter;
ulong global_irq_counter;
bool dump_conf;
bool config_mmio_init;
bool enumerated;
enum ep_pcie_link_status link_status;
bool power_on;
bool suspending;
bool l23_ready;
bool l1ss_enabled;
struct ep_pcie_msi_config msi_cfg;
bool no_notify;
bool client_ready;
atomic_t ep_pcie_dev_wake;
atomic_t perst_deast;
struct ep_pcie_register_event *event_reg;
struct work_struct handle_perst_work;
struct work_struct handle_bme_work;
struct work_struct handle_d3cold_work;
};
extern struct ep_pcie_dev_t ep_pcie_dev;
extern struct ep_pcie_hw hw_drv;
static inline void ep_pcie_write_mask(void __iomem *addr,
u32 clear_mask, u32 set_mask)
{
u32 val;
val = (readl_relaxed(addr) & ~clear_mask) | set_mask;
writel_relaxed(val, addr);
/* ensure register write goes through before next regiser operation */
wmb();
}
static inline void ep_pcie_write_reg(void __iomem *base, u32 offset, u32 value)
{
writel_relaxed(value, base + offset);
/* ensure register write goes through before next regiser operation */
wmb();
}
static inline void ep_pcie_write_reg_field(void __iomem *base, u32 offset,
const u32 mask, u32 val)
{
u32 shift = find_first_bit((void *)&mask, 32);
u32 tmp = readl_relaxed(base + offset);
tmp &= ~mask; /* clear written bits */
val = tmp | (val << shift);
writel_relaxed(val, base + offset);
/* ensure register write goes through before next regiser operation */
wmb();
}
extern int ep_pcie_core_register_event(struct ep_pcie_register_event *reg);
extern int ep_pcie_get_debug_mask(void);
extern void ep_pcie_phy_init(struct ep_pcie_dev_t *dev);
extern bool ep_pcie_phy_is_ready(struct ep_pcie_dev_t *dev);
extern void ep_pcie_reg_dump(struct ep_pcie_dev_t *dev, u32 sel, bool linkdown);
extern void ep_pcie_debugfs_init(struct ep_pcie_dev_t *ep_dev);
extern void ep_pcie_debugfs_exit(void);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,451 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.*/
/*
* Debugging enhancement in MSM PCIe endpoint driver.
*/
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/debugfs.h>
#include "ep_pcie_com.h"
#include "ep_pcie_phy.h"
static struct dentry *dent_ep_pcie;
static struct dentry *dfile_case;
static struct ep_pcie_dev_t *dev;
static void ep_ep_pcie_phy_dump_pcs_debug_bus(struct ep_pcie_dev_t *dev,
u32 cntrl4, u32 cntrl5,
u32 cntrl6, u32 cntrl7)
{
ep_pcie_write_reg(dev->phy, PCIE_PHY_TEST_CONTROL4, cntrl4);
ep_pcie_write_reg(dev->phy, PCIE_PHY_TEST_CONTROL5, cntrl5);
ep_pcie_write_reg(dev->phy, PCIE_PHY_TEST_CONTROL6, cntrl6);
ep_pcie_write_reg(dev->phy, PCIE_PHY_TEST_CONTROL7, cntrl7);
if (!cntrl4 && !cntrl5 && !cntrl6 && !cntrl7) {
EP_PCIE_DUMP(dev,
"PCIe V%d: zero out test control registers\n\n",
dev->rev);
return;
}
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_TEST_CONTROL4: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_TEST_CONTROL4));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_TEST_CONTROL5: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_TEST_CONTROL5));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_TEST_CONTROL6: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_TEST_CONTROL6));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_TEST_CONTROL7: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_TEST_CONTROL7));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_DEBUG_BUS_0_STATUS: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_DEBUG_BUS_0_STATUS));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_DEBUG_BUS_1_STATUS: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_DEBUG_BUS_1_STATUS));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_DEBUG_BUS_2_STATUS: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_DEBUG_BUS_2_STATUS));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_DEBUG_BUS_3_STATUS: 0x%x\n\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_DEBUG_BUS_3_STATUS));
}
static void ep_ep_pcie_phy_dump_pcs_misc_debug_bus(struct ep_pcie_dev_t *dev,
u32 b0, u32 b1, u32 b2, u32 b3)
{
ep_pcie_write_reg(dev->phy, PCIE_PHY_MISC_DEBUG_BUS_BYTE0_INDEX, b0);
ep_pcie_write_reg(dev->phy, PCIE_PHY_MISC_DEBUG_BUS_BYTE1_INDEX, b1);
ep_pcie_write_reg(dev->phy, PCIE_PHY_MISC_DEBUG_BUS_BYTE2_INDEX, b2);
ep_pcie_write_reg(dev->phy, PCIE_PHY_MISC_DEBUG_BUS_BYTE3_INDEX, b3);
if (!b0 && !b1 && !b2 && !b3) {
EP_PCIE_DUMP(dev,
"PCIe V%d: zero out misc debug bus byte index registers\n\n",
dev->rev);
return;
}
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_BYTE0_INDEX: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_BYTE0_INDEX));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_BYTE1_INDEX: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_BYTE1_INDEX));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_BYTE2_INDEX: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_BYTE2_INDEX));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_BYTE3_INDEX: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_BYTE3_INDEX));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_0_STATUS: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_0_STATUS));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_1_STATUS: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_1_STATUS));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_2_STATUS: 0x%x\n", dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_2_STATUS));
EP_PCIE_DUMP(dev,
"PCIe V%d: PCIE_PHY_MISC_DEBUG_BUS_3_STATUS: 0x%x\n\n",
dev->rev,
readl_relaxed(dev->phy + PCIE_PHY_MISC_DEBUG_BUS_3_STATUS));
}
static void ep_pcie_phy_dump(struct ep_pcie_dev_t *dev)
{
int i;
u32 write_val;
EP_PCIE_DUMP(dev, "PCIe V%d: Beginning of PHY debug dump\n\n",
dev->rev);
EP_PCIE_DUMP(dev, "PCIe V%d: PCS Debug Signals\n\n", dev->rev);
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0x01, 0x02, 0x03, 0x0A);
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0x0E, 0x0F, 0x12, 0x13);
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0x18, 0x19, 0x1A, 0x1B);
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0x1C, 0x1D, 0x1E, 0x1F);
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0x20, 0x21, 0x22, 0x23);
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0, 0, 0, 0);
EP_PCIE_DUMP(dev, "PCIe V%d: PCS Misc Debug Signals\n\n", dev->rev);
ep_ep_pcie_phy_dump_pcs_misc_debug_bus(dev, 0x1, 0x2, 0x3, 0x4);
ep_ep_pcie_phy_dump_pcs_misc_debug_bus(dev, 0x5, 0x6, 0x7, 0x8);
ep_ep_pcie_phy_dump_pcs_misc_debug_bus(dev, 0, 0, 0, 0);
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES COM Debug Signals\n\n", dev->rev);
for (i = 0; i < 2; i++) {
write_val = 0x2 + i;
ep_pcie_write_reg(dev->phy, QSERDES_COM_DEBUG_BUS_SEL,
write_val);
EP_PCIE_DUMP(dev,
"PCIe V%d: to QSERDES_COM_DEBUG_BUS_SEL: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + QSERDES_COM_DEBUG_BUS_SEL));
EP_PCIE_DUMP(dev,
"PCIe V%d: QSERDES_COM_DEBUG_BUS0: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + QSERDES_COM_DEBUG_BUS0));
EP_PCIE_DUMP(dev,
"PCIe V%d: QSERDES_COM_DEBUG_BUS1: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + QSERDES_COM_DEBUG_BUS1));
EP_PCIE_DUMP(dev,
"PCIe V%d: QSERDES_COM_DEBUG_BUS2: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + QSERDES_COM_DEBUG_BUS2));
EP_PCIE_DUMP(dev,
"PCIe V%d: QSERDES_COM_DEBUG_BUS3: 0x%x\n\n",
dev->rev,
readl_relaxed(dev->phy + QSERDES_COM_DEBUG_BUS3));
}
ep_pcie_write_reg(dev->phy, QSERDES_COM_DEBUG_BUS_SEL, 0);
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES LANE Debug Signals\n\n",
dev->rev);
for (i = 0; i < 3; i++) {
write_val = 0x1 + i;
ep_pcie_write_reg(dev->phy,
QSERDES_TX_DEBUG_BUS_SEL, write_val);
EP_PCIE_DUMP(dev,
"PCIe V%d: QSERDES_TX_DEBUG_BUS_SEL: 0x%x\n",
dev->rev,
readl_relaxed(dev->phy + QSERDES_TX_DEBUG_BUS_SEL));
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0x30, 0x31, 0x32, 0x33);
}
ep_ep_pcie_phy_dump_pcs_debug_bus(dev, 0, 0, 0, 0);
EP_PCIE_DUMP(dev, "PCIe V%d: End of PHY debug dump\n\n", dev->rev);
}
void ep_pcie_reg_dump(struct ep_pcie_dev_t *dev, u32 sel, bool linkdown)
{
int r, i;
u32 original;
u32 size;
EP_PCIE_DBG(dev,
"PCIe V%d: Dump PCIe reg for 0x%x %s linkdown\n",
dev->rev, sel, linkdown ? "with" : "without");
if (!dev->power_on) {
EP_PCIE_ERR(dev,
"PCIe V%d: the power is already down; can't dump registers\n",
dev->rev);
return;
}
if (linkdown) {
EP_PCIE_DUMP(dev,
"PCIe V%d: dump PARF registers for linkdown case\n",
dev->rev);
original = readl_relaxed(dev->parf + PCIE20_PARF_SYS_CTRL);
for (i = 1; i <= 0x1A; i++) {
ep_pcie_write_mask(dev->parf + PCIE20_PARF_SYS_CTRL,
0xFF0000, i << 16);
EP_PCIE_DUMP(dev,
"PCIe V%d: PARF_SYS_CTRL:0x%x PARF_TEST_BUS:0x%x\n",
dev->rev,
readl_relaxed(dev->parf + PCIE20_PARF_SYS_CTRL),
readl_relaxed(dev->parf +
PCIE20_PARF_TEST_BUS));
}
ep_pcie_write_reg(dev->parf, PCIE20_PARF_SYS_CTRL, original);
}
for (r = 0; r < EP_PCIE_MAX_RES; r++) {
if (!(sel & BIT(r)))
continue;
if ((r == EP_PCIE_RES_PHY) && (dev->phy_rev > 3))
ep_pcie_phy_dump(dev);
size = resource_size(dev->res[r].resource);
EP_PCIE_DUMP(dev,
"\nPCIe V%d: dump registers of %s\n\n",
dev->rev, dev->res[r].name);
for (i = 0; i < size; i += 32) {
EP_PCIE_DUMP(dev,
"0x%04x %08x %08x %08x %08x %08x %08x %08x %08x\n",
i, readl_relaxed(dev->res[r].base + i),
readl_relaxed(dev->res[r].base + (i + 4)),
readl_relaxed(dev->res[r].base + (i + 8)),
readl_relaxed(dev->res[r].base + (i + 12)),
readl_relaxed(dev->res[r].base + (i + 16)),
readl_relaxed(dev->res[r].base + (i + 20)),
readl_relaxed(dev->res[r].base + (i + 24)),
readl_relaxed(dev->res[r].base + (i + 28)));
}
}
}
static void ep_pcie_show_status(struct ep_pcie_dev_t *dev)
{
EP_PCIE_DBG_FS("PCIe: is %s enumerated\n",
dev->enumerated ? "" : "not");
EP_PCIE_DBG_FS("PCIe: link is %s\n",
(dev->link_status == EP_PCIE_LINK_ENABLED)
? "enabled" : "disabled");
EP_PCIE_DBG_FS("the link is %s suspending\n",
dev->suspending ? "" : "not");
EP_PCIE_DBG_FS("the power is %s on\n",
dev->power_on ? "" : "not");
EP_PCIE_DBG_FS("linkdown_counter: %lu\n",
dev->linkdown_counter);
EP_PCIE_DBG_FS("linkup_counter: %lu\n",
dev->linkup_counter);
EP_PCIE_DBG_FS("wake_counter: %lu\n",
dev->wake_counter);
EP_PCIE_DBG_FS("d0_counter: %lu\n",
dev->d0_counter);
EP_PCIE_DBG_FS("d3_counter: %lu\n",
dev->d3_counter);
EP_PCIE_DBG_FS("perst_ast_counter: %lu\n",
dev->perst_ast_counter);
EP_PCIE_DBG_FS("perst_deast_counter: %lu\n",
dev->perst_deast_counter);
}
static ssize_t ep_pcie_cmd_debug(struct file *file,
const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long ret;
char str[MAX_MSG_LEN];
unsigned int testcase = 0;
struct ep_pcie_msi_config msi_cfg;
int i;
struct ep_pcie_hw *phandle = NULL;
struct ep_pcie_iatu entries[2] = {
{0x80000000, 0xbe7fffff, 0, 0},
{0xb1440000, 0xb144ae1e, 0x31440000, 0}
};
struct ep_pcie_db_config chdb_cfg = {0x64, 0x6b, 0xfd4fa000};
struct ep_pcie_db_config erdb_cfg = {0x64, 0x6b, 0xfd4fa080};
phandle = ep_pcie_get_phandle(hw_drv.device_id);
memset(str, 0, sizeof(str));
ret = copy_from_user(str, buf, sizeof(str));
if (ret)
return -EFAULT;
for (i = 0; i < sizeof(str) && (str[i] >= '0') && (str[i] <= '9'); ++i)
testcase = (testcase * 10) + (str[i] - '0');
EP_PCIE_DBG_FS("PCIe: TEST: %d\n", testcase);
switch (testcase) {
case 0: /* output status */
ep_pcie_show_status(dev);
break;
case 1: /* output PHY and PARF registers */
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_PHY) |
BIT(EP_PCIE_RES_PARF), true);
break;
case 2: /* output core registers */
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_DM_CORE), false);
break;
case 3: /* output MMIO registers */
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_MMIO), false);
break;
case 4: /* output ELBI registers */
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_ELBI), false);
break;
case 5: /* output MSI registers */
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_MSI), false);
break;
case 6: /* turn on link */
ep_pcie_enable_endpoint(phandle, EP_PCIE_OPT_ALL);
break;
case 7: /* enumeration */
ep_pcie_enable_endpoint(phandle, EP_PCIE_OPT_ENUM);
break;
case 8: /* turn off link */
ep_pcie_disable_endpoint(phandle);
break;
case 9: /* check MSI */
ep_pcie_get_msi_config(phandle, &msi_cfg);
break;
case 10: /* trigger MSI */
ep_pcie_trigger_msi(phandle, 0);
break;
case 11: /* indicate the status of PCIe link */
EP_PCIE_DBG_FS("\nPCIe: link status is %d\n\n",
ep_pcie_get_linkstatus(phandle));
break;
case 12: /* configure outbound iATU */
ep_pcie_config_outbound_iatu(phandle, entries, 2);
break;
case 13: /* wake up the host */
ep_pcie_wakeup_host(phandle, EP_PCIE_EVENT_PM_D3_HOT);
break;
case 14: /* Configure routing of doorbells */
ep_pcie_config_db_routing(phandle, chdb_cfg, erdb_cfg);
break;
case 21: /* write D3 */
EP_PCIE_DBG_FS("\nPCIe Testcase %d: write D3 to EP\n\n",
testcase);
EP_PCIE_DBG_FS("\nPCIe: 0x44 of EP is 0x%x before change\n\n",
readl_relaxed(dev->dm_core + 0x44));
ep_pcie_write_mask(dev->dm_core + 0x44, 0, 0x3);
EP_PCIE_DBG_FS("\nPCIe: 0x44 of EP is 0x%x now\n\n",
readl_relaxed(dev->dm_core + 0x44));
break;
case 22: /* write D0 */
EP_PCIE_DBG_FS("\nPCIe Testcase %d: write D0 to EP\n\n",
testcase);
EP_PCIE_DBG_FS("\nPCIe: 0x44 of EP is 0x%x before change\n\n",
readl_relaxed(dev->dm_core + 0x44));
ep_pcie_write_mask(dev->dm_core + 0x44, 0x3, 0);
EP_PCIE_DBG_FS("\nPCIe: 0x44 of EP is 0x%x now\n\n",
readl_relaxed(dev->dm_core + 0x44));
break;
case 23: /* assert wake */
EP_PCIE_DBG_FS("\nPCIe Testcase %d: assert wake\n\n",
testcase);
gpio_set_value(dev->gpio[EP_PCIE_GPIO_WAKE].num,
dev->gpio[EP_PCIE_GPIO_WAKE].on);
break;
case 24: /* deassert wake */
EP_PCIE_DBG_FS("\nPCIe Testcase %d: deassert wake\n\n",
testcase);
gpio_set_value(dev->gpio[EP_PCIE_GPIO_WAKE].num,
1 - dev->gpio[EP_PCIE_GPIO_WAKE].on);
break;
case 25: /* output PERST# status */
EP_PCIE_DBG_FS("\nPCIe: PERST# is %d\n\n",
gpio_get_value(dev->gpio[EP_PCIE_GPIO_PERST].num));
break;
case 26: /* output WAKE# status */
EP_PCIE_DBG_FS("\nPCIe: WAKE# is %d\n\n",
gpio_get_value(dev->gpio[EP_PCIE_GPIO_WAKE].num));
break;
case 31: /* output core registers when D3 hot is set by host*/
dev->dump_conf = true;
break;
case 32: /* do not output core registers when D3 hot is set by host*/
dev->dump_conf = false;
break;
case 33: /* output edma registers */
edma_dump();
break;
default:
EP_PCIE_DBG_FS("PCIe: Invalid testcase: %d\n", testcase);
break;
}
if (ret == 0)
return count;
else
return -EFAULT;
}
const struct file_operations ep_pcie_cmd_debug_ops = {
.write = ep_pcie_cmd_debug,
};
void ep_pcie_debugfs_init(struct ep_pcie_dev_t *ep_dev)
{
dev = ep_dev;
dent_ep_pcie = debugfs_create_dir("pcie-ep", 0);
if (IS_ERR(dent_ep_pcie)) {
EP_PCIE_ERR(dev,
"PCIe V%d: fail to create the folder for debug_fs\n",
dev->rev);
return;
}
dfile_case = debugfs_create_file("case", 0664,
dent_ep_pcie, 0,
&ep_pcie_cmd_debug_ops);
if (!dfile_case || IS_ERR(dfile_case)) {
EP_PCIE_ERR(dev,
"PCIe V%d: fail to create the file for case\n",
dev->rev);
goto case_error;
}
EP_PCIE_DBG2(dev,
"PCIe V%d: debugfs is enabled\n",
dev->rev);
return;
case_error:
debugfs_remove(dent_ep_pcie);
}
void ep_pcie_debugfs_exit(void)
{
debugfs_remove(dfile_case);
debugfs_remove(dent_ep_pcie);
}

View file

@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, 2019-2020, The Linux Foundation. All rights reserved.*/
/*
* MSM PCIe PHY endpoint mode
*/
#include "ep_pcie_com.h"
#include "ep_pcie_phy.h"
void ep_pcie_phy_init(struct ep_pcie_dev_t *dev)
{
switch (dev->phy_rev) {
case 3:
EP_PCIE_DBG(dev,
"PCIe V%d: PHY V%d: Initializing 20nm QMP phy - 100MHz\n",
dev->rev, dev->phy_rev);
break;
case 4:
EP_PCIE_DBG(dev,
"PCIe V%d: PHY V%d: Initializing 14nm QMP phy - 100MHz\n",
dev->rev, dev->phy_rev);
break;
case 5:
EP_PCIE_DBG(dev,
"PCIe V%d: PHY V%d: Initializing 10nm QMP phy - 100MHz\n",
dev->rev, dev->phy_rev);
break;
case 6:
EP_PCIE_DBG(dev,
"PCIe V%d: PHY V%d: Initializing 7nm QMP phy - 100MHz\n",
dev->rev, dev->phy_rev);
break;
default:
EP_PCIE_ERR(dev,
"PCIe V%d: Unexpected phy version %d is caught\n",
dev->rev, dev->phy_rev);
}
if (dev->phy_init_len && dev->phy_init) {
int i;
struct ep_pcie_phy_info_t *phy_init;
EP_PCIE_DBG(dev,
"PCIe V%d: PHY V%d: process the sequence specified by DT\n",
dev->rev, dev->phy_rev);
i = dev->phy_init_len;
phy_init = dev->phy_init;
while (i--) {
ep_pcie_write_reg(dev->phy,
phy_init->offset,
phy_init->val);
if (phy_init->delay)
usleep_range(phy_init->delay,
phy_init->delay + 1);
phy_init++;
}
return;
}
ep_pcie_write_reg(dev->phy, PCIE_PHY_SW_RESET, 0x01);
ep_pcie_write_reg(dev->phy, PCIE_PHY_POWER_DOWN_CONTROL, 0x01);
/* Common block settings */
ep_pcie_write_reg(dev->phy, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18);
ep_pcie_write_reg(dev->phy, QSERDES_COM_CLK_ENABLE1, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_BG_TRIM, 0x0F);
ep_pcie_write_reg(dev->phy, QSERDES_COM_LOCK_CMP_EN, 0x01);
ep_pcie_write_reg(dev->phy, QSERDES_COM_VCO_TUNE_MAP, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_VCO_TUNE_TIMER1, 0xFF);
ep_pcie_write_reg(dev->phy, QSERDES_COM_VCO_TUNE_TIMER2, 0x1F);
ep_pcie_write_reg(dev->phy, QSERDES_COM_CMN_CONFIG, 0x06);
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_IVCO, 0x0F);
ep_pcie_write_reg(dev->phy, QSERDES_COM_HSCLK_SEL, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_SVS_MODE_CLK_SEL, 0x01);
ep_pcie_write_reg(dev->phy, QSERDES_COM_CORE_CLK_EN, 0x20);
ep_pcie_write_reg(dev->phy, QSERDES_COM_CORECLK_DIV, 0x0A);
ep_pcie_write_reg(dev->phy, QSERDES_COM_RESETSM_CNTRL, 0x20);
ep_pcie_write_reg(dev->phy, QSERDES_COM_BG_TIMER, 0x01);
/* PLL Config Settings */
ep_pcie_write_reg(dev->phy, QSERDES_COM_SYSCLK_EN_SEL, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_DEC_START_MODE0, 0x19);
ep_pcie_write_reg(dev->phy, QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_LOCK_CMP3_MODE0, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_LOCK_CMP2_MODE0, 0x02);
ep_pcie_write_reg(dev->phy, QSERDES_COM_LOCK_CMP1_MODE0, 0x7F);
ep_pcie_write_reg(dev->phy, QSERDES_COM_CLK_SELECT, 0x30);
ep_pcie_write_reg(dev->phy, QSERDES_COM_SYS_CLK_CTRL, 0x06);
ep_pcie_write_reg(dev->phy, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E);
ep_pcie_write_reg(dev->phy, QSERDES_COM_CP_CTRL_MODE0, 0x3F);
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_RCTRL_MODE0, 0x1A);
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_CCTRL_MODE0, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x03);
ep_pcie_write_reg(dev->phy, QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0xFF);
/* TX settings */
ep_pcie_write_reg(dev->phy, QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
0x45);
ep_pcie_write_reg(dev->phy, QSERDES_TX_LANE_MODE, 0x06);
ep_pcie_write_reg(dev->phy, QSERDES_TX_RES_CODE_LANE_OFFSET, 0x02);
ep_pcie_write_reg(dev->phy, QSERDES_TX_RCV_DETECT_LVL_2, 0x12);
/* RX settings */
ep_pcie_write_reg(dev->phy, QSERDES_RX_SIGDET_ENABLES, 0x1C);
ep_pcie_write_reg(dev->phy, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14);
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01);
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00);
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xDB);
ep_pcie_write_reg(dev->phy, QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE,
0x4B);
ep_pcie_write_reg(dev->phy, QSERDES_RX_UCDR_SO_GAIN, 0x04);
ep_pcie_write_reg(dev->phy, QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04);
/* EP_REF_CLK settings */
ep_pcie_write_reg(dev->phy, QSERDES_COM_CLK_EP_DIV, 0x19);
ep_pcie_write_reg(dev->phy, PCIE_PHY_ENDPOINT_REFCLK_DRIVE, 0x00);
/* PCIE L1SS settings */
ep_pcie_write_reg(dev->phy, PCIE_PHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40);
ep_pcie_write_reg(dev->phy, PCIE_PHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB,
0x00);
ep_pcie_write_reg(dev->phy, PCIE_PHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB,
0x40);
ep_pcie_write_reg(dev->phy, PCIE_PHY_LP_WAKEUP_DLY_TIME_AUXCLK_MSB,
0x00);
ep_pcie_write_reg(dev->phy, PCIE_PHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40);
ep_pcie_write_reg(dev->phy, PCIE_PHY_PLL_LOCK_CHK_DLY_TIME, 0x73);
/* PCS settings */
ep_pcie_write_reg(dev->phy, PCIE_PHY_SIGDET_CNTRL, 0x07);
ep_pcie_write_reg(dev->phy, PCIE_PHY_RX_SIGDET_LVL, 0x99);
ep_pcie_write_reg(dev->phy, PCIE_PHY_TXDEEMPH_M6DB_V0, 0x15);
ep_pcie_write_reg(dev->phy, PCIE_PHY_TXDEEMPH_M3P5DB_V0, 0x0E);
ep_pcie_write_reg(dev->phy, PCIE_PHY_SW_RESET, 0x00);
ep_pcie_write_reg(dev->phy, PCIE_PHY_START_CONTROL, 0x03);
}
bool ep_pcie_phy_is_ready(struct ep_pcie_dev_t *dev)
{
u32 offset;
if (dev->phy_status_reg)
offset = dev->phy_status_reg;
else
offset = PCIE_PHY_PCS_STATUS;
if (readl_relaxed(dev->phy + offset) & dev->phy_status_bit_mask_bit)
return false;
else
return true;
}

View file

@ -0,0 +1,454 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015, 2017, 2020 The Linux Foundation. All rights reserved.*/
#ifndef __EP_PCIE_PHY_H
#define __EP_PCIE_PHY_H
#define QSERDES_COM_ATB_SEL1 0x000
#define QSERDES_COM_ATB_SEL2 0x004
#define QSERDES_COM_FREQ_UPDATE 0x008
#define QSERDES_COM_BG_TIMER 0x00C
#define QSERDES_COM_SSC_EN_CENTER 0x010
#define QSERDES_COM_SSC_ADJ_PER1 0x014
#define QSERDES_COM_SSC_ADJ_PER2 0x018
#define QSERDES_COM_SSC_PER1 0x01C
#define QSERDES_COM_SSC_PER2 0x020
#define QSERDES_COM_SSC_STEP_SIZE1 0x024
#define QSERDES_COM_SSC_STEP_SIZE2 0x028
#define QSERDES_COM_POST_DIV 0x02C
#define QSERDES_COM_POST_DIV_MUX 0x030
#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x034
#define QSERDES_COM_CLK_ENABLE1 0x038
#define QSERDES_COM_SYS_CLK_CTRL 0x03C
#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x040
#define QSERDES_COM_PLL_EN 0x044
#define QSERDES_COM_PLL_IVCO 0x048
#define QSERDES_COM_LOCK_CMP1_MODE0 0x04C
#define QSERDES_COM_LOCK_CMP2_MODE0 0x050
#define QSERDES_COM_LOCK_CMP3_MODE0 0x054
#define QSERDES_COM_LOCK_CMP1_MODE1 0x058
#define QSERDES_COM_LOCK_CMP2_MODE1 0x05C
#define QSERDES_COM_LOCK_CMP3_MODE1 0x060
#define QSERDES_COM_CMN_RSVD0 0x064
#define QSERDES_COM_EP_CLOCK_DETECT_CTRL 0x068
#define QSERDES_COM_SYSCLK_DET_COMP_STATUS 0x06C
#define QSERDES_COM_BG_TRIM 0x070
#define QSERDES_COM_CLK_EP_DIV 0x074
#define QSERDES_COM_CP_CTRL_MODE0 0x078
#define QSERDES_COM_CP_CTRL_MODE1 0x07C
#define QSERDES_COM_CMN_RSVD1 0x080
#define QSERDES_COM_PLL_RCTRL_MODE0 0x084
#define QSERDES_COM_PLL_RCTRL_MODE1 0x088
#define QSERDES_COM_CMN_RSVD2 0x08C
#define QSERDES_COM_PLL_CCTRL_MODE0 0x090
#define QSERDES_COM_PLL_CCTRL_MODE1 0x094
#define QSERDES_COM_CMN_RSVD3 0x098
#define QSERDES_COM_PLL_CNTRL 0x09C
#define QSERDES_COM_PHASE_SEL_CTRL 0x0A0
#define QSERDES_COM_PHASE_SEL_DC 0x0A4
#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0A8
#define QSERDES_COM_SYSCLK_EN_SEL 0x0AC
#define QSERDES_COM_CML_SYSCLK_SEL 0x0B0
#define QSERDES_COM_RESETSM_CNTRL 0x0B4
#define QSERDES_COM_RESETSM_CNTRL2 0x0B8
#define QSERDES_COM_RESTRIM_CTRL 0x0BC
#define QSERDES_COM_RESTRIM_CTRL2 0x0C0
#define QSERDES_COM_RESCODE_DIV_NUM 0x0C4
#define QSERDES_COM_LOCK_CMP_EN 0x0C8
#define QSERDES_COM_LOCK_CMP_CFG 0x0CC
#define QSERDES_COM_DEC_START_MODE0 0x0D0
#define QSERDES_COM_DEC_START_MODE1 0x0D4
#define QSERDES_COM_VCOCAL_DEADMAN_CTRL 0x0D8
#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x0DC
#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x0E0
#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x0E4
#define QSERDES_COM_DIV_FRAC_START1_MODE1 0x0E8
#define QSERDES_COM_DIV_FRAC_START2_MODE1 0x0EC
#define QSERDES_COM_DIV_FRAC_START3_MODE1 0x0F0
#define QSERDES_COM_VCO_TUNE_MINVAL1 0x0F4
#define QSERDES_COM_VCO_TUNE_MINVAL2 0x0F8
#define QSERDES_COM_CMN_RSVD4 0x0FC
#define QSERDES_COM_INTEGLOOP_INITVAL 0x100
#define QSERDES_COM_INTEGLOOP_EN 0x104
#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10C
#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x110
#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x114
#define QSERDES_COM_VCO_TUNE_MAXVAL1 0x118
#define QSERDES_COM_VCO_TUNE_MAXVAL2 0x11C
#define QSERDES_COM_RES_TRIM_CONTROL2 0x120
#define QSERDES_COM_VCO_TUNE_CTRL 0x124
#define QSERDES_COM_VCO_TUNE_MAP 0x128
#define QSERDES_COM_VCO_TUNE1_MODE0 0x12C
#define QSERDES_COM_VCO_TUNE2_MODE0 0x130
#define QSERDES_COM_VCO_TUNE1_MODE1 0x134
#define QSERDES_COM_VCO_TUNE2_MODE1 0x138
#define QSERDES_COM_VCO_TUNE_INITVAL1 0x13C
#define QSERDES_COM_VCO_TUNE_INITVAL2 0x140
#define QSERDES_COM_VCO_TUNE_TIMER1 0x144
#define QSERDES_COM_VCO_TUNE_TIMER2 0x148
#define QSERDES_COM_SAR 0x14C
#define QSERDES_COM_SAR_CLK 0x150
#define QSERDES_COM_SAR_CODE_OUT_STATUS 0x154
#define QSERDES_COM_SAR_CODE_READY_STATUS 0x158
#define QSERDES_COM_CMN_STATUS 0x15C
#define QSERDES_COM_RESET_SM_STATUS 0x160
#define QSERDES_COM_RESTRIM_CODE_STATUS 0x164
#define QSERDES_COM_PLLCAL_CODE1_STATUS 0x168
#define QSERDES_COM_PLLCAL_CODE2_STATUS 0x16C
#define QSERDES_COM_BG_CTRL 0x170
#define QSERDES_COM_CLK_SELECT 0x174
#define QSERDES_COM_HSCLK_SEL 0x178
#define QSERDES_COM_PLL_ANALOG 0x180
#define QSERDES_COM_CORECLK_DIV 0x184
#define QSERDES_COM_SW_RESET 0x188
#define QSERDES_COM_CORE_CLK_EN 0x18C
#define QSERDES_COM_C_READY_STATUS 0x190
#define QSERDES_COM_CMN_CONFIG 0x194
#define QSERDES_COM_CMN_RATE_OVERRIDE 0x198
#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19C
#define QSERDES_COM_DEBUG_BUS0 0x1A0
#define QSERDES_COM_DEBUG_BUS1 0x1A4
#define QSERDES_COM_DEBUG_BUS2 0x1A8
#define QSERDES_COM_DEBUG_BUS3 0x1AC
#define QSERDES_COM_DEBUG_BUS_SEL 0x1B0
#define QSERDES_COM_CMN_MISC1 0x1B4
#define QSERDES_COM_CMN_MISC2 0x1B8
#define QSERDES_COM_CORECLK_DIV_MODE1 0x1BC
#define QSERDES_COM_CMN_RSVD5 0x1C0
#define QSERDES_TX_BIST_MODE_LANENO 0x200
#define QSERDES_TX_BIST_INVERT 0x204
#define QSERDES_TX_CLKBUF_ENABLE 0x208
#define QSERDES_TX_CMN_CONTROL_ONE 0x20C
#define QSERDES_TX_CMN_CONTROL_TWO 0x210
#define QSERDES_TX_CMN_CONTROL_THREE 0x214
#define QSERDES_TX_TX_EMP_POST1_LVL 0x218
#define QSERDES_TX_TX_POST2_EMPH 0x21C
#define QSERDES_TX_TX_BOOST_LVL_UP_DN 0x220
#define QSERDES_TX_HP_PD_ENABLES 0x224
#define QSERDES_TX_TX_IDLE_LVL_LARGE_AMP 0x228
#define QSERDES_TX_TX_DRV_LVL 0x22C
#define QSERDES_TX_TX_DRV_LVL_OFFSET 0x230
#define QSERDES_TX_RESET_TSYNC_EN 0x234
#define QSERDES_TX_PRE_STALL_LDO_BOOST_EN 0x238
#define QSERDES_TX_TX_BAND 0x23C
#define QSERDES_TX_SLEW_CNTL 0x240
#define QSERDES_TX_INTERFACE_SELECT 0x244
#define QSERDES_TX_LPB_EN 0x248
#define QSERDES_TX_RES_CODE_LANE_TX 0x24C
#define QSERDES_TX_RES_CODE_LANE_RX 0x250
#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x254
#define QSERDES_TX_PERL_LENGTH1 0x258
#define QSERDES_TX_PERL_LENGTH2 0x25C
#define QSERDES_TX_SERDES_BYP_EN_OUT 0x260
#define QSERDES_TX_DEBUG_BUS_SEL 0x264
#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x268
#define QSERDES_TX_TX_POL_INV 0x26C
#define QSERDES_TX_PARRATE_REC_DETECT_IDLE_EN 0x270
#define QSERDES_TX_BIST_PATTERN1 0x274
#define QSERDES_TX_BIST_PATTERN2 0x278
#define QSERDES_TX_BIST_PATTERN3 0x27C
#define QSERDES_TX_BIST_PATTERN4 0x280
#define QSERDES_TX_BIST_PATTERN5 0x284
#define QSERDES_TX_BIST_PATTERN6 0x288
#define QSERDES_TX_BIST_PATTERN7 0x28C
#define QSERDES_TX_BIST_PATTERN8 0x290
#define QSERDES_TX_LANE_MODE 0x294
#define QSERDES_TX_IDAC_CAL_LANE_MODE 0x298
#define QSERDES_TX_IDAC_CAL_LANE_MODE_CONFIGURATION 0x29C
#define QSERDES_TX_ATB_SEL1 0x2A0
#define QSERDES_TX_ATB_SEL2 0x2A4
#define QSERDES_TX_RCV_DETECT_LVL 0x2A8
#define QSERDES_TX_RCV_DETECT_LVL_2 0x2AC
#define QSERDES_TX_PRBS_SEED1 0x2B0
#define QSERDES_TX_PRBS_SEED2 0x2B4
#define QSERDES_TX_PRBS_SEED3 0x2B8
#define QSERDES_TX_PRBS_SEED4 0x2BC
#define QSERDES_TX_RESET_GEN 0x2C0
#define QSERDES_TX_RESET_GEN_MUXES 0x2C4
#define QSERDES_TX_TRAN_DRVR_EMP_EN 0x2C8
#define QSERDES_TX_TX_INTERFACE_MODE 0x2CC
#define QSERDES_TX_PWM_CTRL 0x2D0
#define QSERDES_TX_PWM_ENCODED_OR_DATA 0x2D4
#define QSERDES_TX_PWM_GEAR_1_DIVIDER_BAND2 0x2D8
#define QSERDES_TX_PWM_GEAR_2_DIVIDER_BAND2 0x2DC
#define QSERDES_TX_PWM_GEAR_3_DIVIDER_BAND2 0x2E0
#define QSERDES_TX_PWM_GEAR_4_DIVIDER_BAND2 0x2E4
#define QSERDES_TX_PWM_GEAR_1_DIVIDER_BAND0_1 0x2E8
#define QSERDES_TX_PWM_GEAR_2_DIVIDER_BAND0_1 0x2EC
#define QSERDES_TX_PWM_GEAR_3_DIVIDER_BAND0_1 0x2F0
#define QSERDES_TX_PWM_GEAR_4_DIVIDER_BAND0_1 0x2F4
#define QSERDES_TX_VMODE_CTRL1 0x2F8
#define QSERDES_TX_VMODE_CTRL2 0x2FC
#define QSERDES_TX_TX_ALOG_INTF_OBSV_CNTL 0x300
#define QSERDES_TX_BIST_STATUS 0x304
#define QSERDES_TX_BIST_ERROR_COUNT1 0x308
#define QSERDES_TX_BIST_ERROR_COUNT2 0x30C
#define QSERDES_TX_TX_ALOG_INTF_OBSV 0x310
#define QSERDES_RX_UCDR_FO_GAIN_HALF 0x400
#define QSERDES_RX_UCDR_FO_GAIN_QUARTER 0x404
#define QSERDES_RX_UCDR_FO_GAIN_EIGHTH 0x408
#define QSERDES_RX_UCDR_FO_GAIN 0x40C
#define QSERDES_RX_UCDR_SO_GAIN_HALF 0x410
#define QSERDES_RX_UCDR_SO_GAIN_QUARTER 0x414
#define QSERDES_RX_UCDR_SO_GAIN_EIGHTH 0x418
#define QSERDES_RX_UCDR_SO_GAIN 0x41C
#define QSERDES_RX_UCDR_SVS_FO_GAIN_HALF 0x420
#define QSERDES_RX_UCDR_SVS_FO_GAIN_QUARTER 0x424
#define QSERDES_RX_UCDR_SVS_FO_GAIN_EIGHTH 0x428
#define QSERDES_RX_UCDR_SVS_FO_GAIN 0x42C
#define QSERDES_RX_UCDR_SVS_SO_GAIN_HALF 0x430
#define QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER 0x434
#define QSERDES_RX_UCDR_SVS_SO_GAIN_EIGHTH 0x438
#define QSERDES_RX_UCDR_SVS_SO_GAIN 0x43C
#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x440
#define QSERDES_RX_UCDR_FD_GAIN 0x444
#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x448
#define QSERDES_RX_UCDR_FO_TO_SO_DELAY 0x44C
#define QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW 0x450
#define QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH 0x454
#define QSERDES_RX_UCDR_MODULATE 0x458
#define QSERDES_RX_UCDR_PI_CONTROLS 0x45C
#define QSERDES_RX_RBIST_CONTROL 0x460
#define QSERDES_RX_AUX_CONTROL 0x464
#define QSERDES_RX_AUX_DATA_TCOARSE 0x468
#define QSERDES_RX_AUX_DATA_TFINE_LSB 0x46C
#define QSERDES_RX_AUX_DATA_TFINE_MSB 0x470
#define QSERDES_RX_RCLK_AUXDATA_SEL 0x474
#define QSERDES_RX_AC_JTAG_ENABLE 0x478
#define QSERDES_RX_AC_JTAG_INITP 0x47C
#define QSERDES_RX_AC_JTAG_INITN 0x480
#define QSERDES_RX_AC_JTAG_LVL 0x484
#define QSERDES_RX_AC_JTAG_MODE 0x488
#define QSERDES_RX_AC_JTAG_RESET 0x48C
#define QSERDES_RX_RX_TERM_BW 0x490
#define QSERDES_RX_RX_RCVR_IQ_EN 0x494
#define QSERDES_RX_RX_IDAC_I_DC_OFFSETS 0x498
#define QSERDES_RX_RX_IDAC_IBAR_DC_OFFSETS 0x49C
#define QSERDES_RX_RX_IDAC_Q_DC_OFFSETS 0x4A0
#define QSERDES_RX_RX_IDAC_QBAR_DC_OFFSETS 0x4A4
#define QSERDES_RX_RX_IDAC_A_DC_OFFSETS 0x4A8
#define QSERDES_RX_RX_IDAC_ABAR_DC_OFFSETS 0x4AC
#define QSERDES_RX_RX_IDAC_EN 0x4B0
#define QSERDES_RX_RX_IDAC_ENABLES 0x4B4
#define QSERDES_RX_RX_IDAC_SIGN 0x4B8
#define QSERDES_RX_RX_HIGHZ_HIGHRATE 0x4BC
#define QSERDES_RX_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x4C0
#define QSERDES_RX_RX_EQ_GAIN1_LSB 0x4C4
#define QSERDES_RX_RX_EQ_GAIN1_MSB 0x4C8
#define QSERDES_RX_RX_EQ_GAIN2_LSB 0x4CC
#define QSERDES_RX_RX_EQ_GAIN2_MSB 0x4D0
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1 0x4D4
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x4D8
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x4DC
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x4E0
#define QSERDES_RX_RX_IDAC_CAL_CONFIGURATION 0x4E4
#define QSERDES_RX_RX_IDAC_TSETTLE_LOW 0x4E8
#define QSERDES_RX_RX_IDAC_TSETTLE_HIGH 0x4EC
#define QSERDES_RX_RX_IDAC_ENDSAMP_LOW 0x4F0
#define QSERDES_RX_RX_IDAC_ENDSAMP_HIGH 0x4F4
#define QSERDES_RX_RX_IDAC_MIDPOINT_LOW 0x4F8
#define QSERDES_RX_RX_IDAC_MIDPOINT_HIGH 0x4FC
#define QSERDES_RX_RX_EQ_OFFSET_LSB 0x500
#define QSERDES_RX_RX_EQ_OFFSET_MSB 0x504
#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x508
#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x50C
#define QSERDES_RX_SIGDET_ENABLES 0x510
#define QSERDES_RX_SIGDET_CNTRL 0x514
#define QSERDES_RX_SIGDET_LVL 0x518
#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x51C
#define QSERDES_RX_RX_BAND 0x520
#define QSERDES_RX_CDR_FREEZE_UP_DN 0x524
#define QSERDES_RX_CDR_RESET_OVERRIDE 0x528
#define QSERDES_RX_RX_INTERFACE_MODE 0x52C
#define QSERDES_RX_JITTER_GEN_MODE 0x530
#define QSERDES_RX_BUJ_AMP 0x534
#define QSERDES_RX_SJ_AMP1 0x538
#define QSERDES_RX_SJ_AMP2 0x53C
#define QSERDES_RX_SJ_PER1 0x540
#define QSERDES_RX_SJ_PER2 0x544
#define QSERDES_RX_BUJ_STEP_FREQ1 0x548
#define QSERDES_RX_BUJ_STEP_FREQ2 0x54C
#define QSERDES_RX_PPM_OFFSET1 0x550
#define QSERDES_RX_PPM_OFFSET2 0x554
#define QSERDES_RX_SIGN_PPM_PERIOD1 0x558
#define QSERDES_RX_SIGN_PPM_PERIOD2 0x55C
#define QSERDES_RX_SSC_CTRL 0x560
#define QSERDES_RX_SSC_COUNT1 0x564
#define QSERDES_RX_SSC_COUNT2 0x568
#define QSERDES_RX_RX_ALOG_INTF_OBSV_CNTL 0x56C
#define QSERDES_RX_RX_PWM_ENABLE_AND_DATA 0x570
#define QSERDES_RX_RX_PWM_GEAR1_TIMEOUT_COUNT 0x574
#define QSERDES_RX_RX_PWM_GEAR2_TIMEOUT_COUNT 0x578
#define QSERDES_RX_RX_PWM_GEAR3_TIMEOUT_COUNT 0x57C
#define QSERDES_RX_RX_PWM_GEAR4_TIMEOUT_COUNT 0x580
#define QSERDES_RX_PI_CTRL1 0x584
#define QSERDES_RX_PI_CTRL2 0x588
#define QSERDES_RX_PI_QUAD 0x58C
#define QSERDES_RX_IDATA1 0x590
#define QSERDES_RX_IDATA2 0x594
#define QSERDES_RX_AUX_DATA1 0x598
#define QSERDES_RX_AUX_DATA2 0x59C
#define QSERDES_RX_AC_JTAG_OUTP 0x5A0
#define QSERDES_RX_AC_JTAG_OUTN 0x5A4
#define QSERDES_RX_RX_SIGDET 0x5A8
#define QSERDES_RX_RX_VDCOFF 0x5AC
#define QSERDES_RX_IDAC_CAL_ON 0x5B0
#define QSERDES_RX_IDAC_STATUS_I 0x5B4
#define QSERDES_RX_IDAC_STATUS_IBAR 0x5B8
#define QSERDES_RX_IDAC_STATUS_Q 0x5BC
#define QSERDES_RX_IDAC_STATUS_QBAR 0x5C0
#define QSERDES_RX_IDAC_STATUS_A 0x5C4
#define QSERDES_RX_IDAC_STATUS_ABAR 0x5C8
#define QSERDES_RX_CALST_STATUS_I 0x5CC
#define QSERDES_RX_CALST_STATUS_Q 0x5D0
#define QSERDES_RX_CALST_STATUS_A 0x5D4
#define QSERDES_RX_RX_ALOG_INTF_OBSV 0x5D8
#define QSERDES_RX_READ_EQCODE 0x5DC
#define QSERDES_RX_READ_OFFSETCODE 0x5E0
#define QSERDES_RX_IA_ERROR_COUNTER_LOW 0x5E4
#define QSERDES_RX_IA_ERROR_COUNTER_HIGH 0x5E8
#define PCIE_PHY_MISC_DEBUG_BUS_BYTE0_INDEX 0x600
#define PCIE_PHY_MISC_DEBUG_BUS_BYTE1_INDEX 0x604
#define PCIE_PHY_MISC_DEBUG_BUS_BYTE2_INDEX 0x608
#define PCIE_PHY_MISC_DEBUG_BUS_BYTE3_INDEX 0x60C
#define PCIE_PHY_MISC_PLACEHOLDER_STATUS 0x610
#define PCIE_PHY_MISC_DEBUG_BUS_0_STATUS 0x614
#define PCIE_PHY_MISC_DEBUG_BUS_1_STATUS 0x618
#define PCIE_PHY_MISC_DEBUG_BUS_2_STATUS 0x61C
#define PCIE_PHY_MISC_DEBUG_BUS_3_STATUS 0x620
#define PCIE_PHY_MISC_OSC_DTCT_STATUS 0x624
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG1 0x628
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG2 0x62C
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG3 0x630
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG4 0x634
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG5 0x638
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG6 0x63C
#define PCIE_PHY_MISC_OSC_DTCT_CONFIG7 0x640
#define PCIE_PHY_SW_RESET 0x800
#define PCIE_PHY_POWER_DOWN_CONTROL 0x804
#define PCIE_PHY_START_CONTROL 0x808
#define PCIE_PHY_TXMGN_V0 0x80C
#define PCIE_PHY_TXMGN_V1 0x810
#define PCIE_PHY_TXMGN_V2 0x814
#define PCIE_PHY_TXMGN_V3 0x818
#define PCIE_PHY_TXMGN_V4 0x81C
#define PCIE_PHY_TXMGN_LS 0x820
#define PCIE_PHY_TXDEEMPH_M6DB_V0 0x824
#define PCIE_PHY_TXDEEMPH_M3P5DB_V0 0x828
#define PCIE_PHY_TXDEEMPH_M6DB_V1 0x82C
#define PCIE_PHY_TXDEEMPH_M3P5DB_V1 0x830
#define PCIE_PHY_TXDEEMPH_M6DB_V2 0x834
#define PCIE_PHY_TXDEEMPH_M3P5DB_V2 0x838
#define PCIE_PHY_TXDEEMPH_M6DB_V3 0x83C
#define PCIE_PHY_TXDEEMPH_M3P5DB_V3 0x840
#define PCIE_PHY_TXDEEMPH_M6DB_V4 0x844
#define PCIE_PHY_TXDEEMPH_M3P5DB_V4 0x848
#define PCIE_PHY_TXDEEMPH_M6DB_LS 0x84C
#define PCIE_PHY_TXDEEMPH_M3P5DB_LS 0x850
#define PCIE_PHY_ENDPOINT_REFCLK_DRIVE 0x854
#define PCIE_PHY_RX_IDLE_DTCT_CNTRL 0x858
#define PCIE_PHY_RATE_SLEW_CNTRL 0x85C
#define PCIE_PHY_POWER_STATE_CONFIG1 0x860
#define PCIE_PHY_POWER_STATE_CONFIG2 0x864
#define PCIE_PHY_POWER_STATE_CONFIG3 0x868
#define PCIE_PHY_POWER_STATE_CONFIG4 0x86C
#define PCIE_PHY_RCVR_DTCT_DLY_P1U2_L 0x870
#define PCIE_PHY_RCVR_DTCT_DLY_P1U2_H 0x874
#define PCIE_PHY_RCVR_DTCT_DLY_U3_L 0x878
#define PCIE_PHY_RCVR_DTCT_DLY_U3_H 0x87C
#define PCIE_PHY_LOCK_DETECT_CONFIG1 0x880
#define PCIE_PHY_LOCK_DETECT_CONFIG2 0x884
#define PCIE_PHY_LOCK_DETECT_CONFIG3 0x888
#define PCIE_PHY_TSYNC_RSYNC_TIME 0x88C
#define PCIE_PHY_SIGDET_LOW_2_IDLE_TIME 0x890
#define PCIE_PHY_BEACON_2_IDLE_TIME_L 0x894
#define PCIE_PHY_BEACON_2_IDLE_TIME_H 0x898
#define PCIE_PHY_PWRUP_RESET_DLY_TIME_SYSCLK 0x89C
#define PCIE_PHY_PWRUP_RESET_DLY_TIME_AUXCLK 0x8A0
#define PCIE_PHY_LP_WAKEUP_DLY_TIME_AUXCLK 0x8A4
#define PCIE_PHY_PLL_LOCK_CHK_DLY_TIME 0x8A8
#define PCIE_PHY_LFPS_DET_HIGH_COUNT_VAL 0x8AC
#define PCIE_PHY_LFPS_TX_ECSTART_EQTLOCK 0x8B0
#define PCIE_PHY_LFPS_TX_END_CNT_P2U3_START 0x8B4
#define PCIE_PHY_RXEQTRAINING_WAIT_TIME 0x8B8
#define PCIE_PHY_RXEQTRAINING_RUN_TIME 0x8BC
#define PCIE_PHY_TXONESZEROS_RUN_LENGTH 0x8C0
#define PCIE_PHY_FLL_CNTRL1 0x8C4
#define PCIE_PHY_FLL_CNTRL2 0x8C8
#define PCIE_PHY_FLL_CNT_VAL_L 0x8CC
#define PCIE_PHY_FLL_CNT_VAL_H_TOL 0x8D0
#define PCIE_PHY_FLL_MAN_CODE 0x8D4
#define PCIE_PHY_AUTONOMOUS_MODE_CTRL 0x8D8
#define PCIE_PHY_LFPS_RXTERM_IRQ_CLEAR 0x8DC
#define PCIE_PHY_ARCVR_DTCT_EN_PERIOD 0x8E0
#define PCIE_PHY_ARCVR_DTCT_CM_DLY 0x8E4
#define PCIE_PHY_ALFPS_DEGLITCH_VAL 0x8E8
#define PCIE_PHY_INSIG_SW_CTRL1 0x8EC
#define PCIE_PHY_INSIG_SW_CTRL2 0x8F0
#define PCIE_PHY_INSIG_SW_CTRL3 0x8F4
#define PCIE_PHY_INSIG_MX_CTRL1 0x8F8
#define PCIE_PHY_INSIG_MX_CTRL2 0x8FC
#define PCIE_PHY_INSIG_MX_CTRL3 0x900
#define PCIE_PHY_OUTSIG_SW_CTRL1 0x904
#define PCIE_PHY_OUTSIG_MX_CTRL1 0x908
#define PCIE_PHY_CLK_DEBUG_BYPASS_CTRL 0x90C
#define PCIE_PHY_TEST_CONTROL 0x910
#define PCIE_PHY_TEST_CONTROL2 0x914
#define PCIE_PHY_TEST_CONTROL3 0x918
#define PCIE_PHY_TEST_CONTROL4 0x91C
#define PCIE_PHY_TEST_CONTROL5 0x920
#define PCIE_PHY_TEST_CONTROL6 0x924
#define PCIE_PHY_TEST_CONTROL7 0x928
#define PCIE_PHY_COM_RESET_CONTROL 0x92C
#define PCIE_PHY_BIST_CTRL 0x930
#define PCIE_PHY_PRBS_POLY0 0x934
#define PCIE_PHY_PRBS_POLY1 0x938
#define PCIE_PHY_PRBS_SEED0 0x93C
#define PCIE_PHY_PRBS_SEED1 0x940
#define PCIE_PHY_FIXED_PAT_CTRL 0x944
#define PCIE_PHY_FIXED_PAT0 0x948
#define PCIE_PHY_FIXED_PAT1 0x94C
#define PCIE_PHY_FIXED_PAT2 0x950
#define PCIE_PHY_FIXED_PAT3 0x954
#define PCIE_PHY_COM_CLK_SWITCH_CTRL 0x958
#define PCIE_PHY_ELECIDLE_DLY_SEL 0x95C
#define PCIE_PHY_SPARE1 0x960
#define PCIE_PHY_BIST_CHK_ERR_CNT_L_STATUS 0x964
#define PCIE_PHY_BIST_CHK_ERR_CNT_H_STATUS 0x968
#define PCIE_PHY_BIST_CHK_STATUS 0x96C
#define PCIE_PHY_LFPS_RXTERM_IRQ_SOURCE_STATUS 0x970
#define PCIE_PHY_PCS_STATUS 0x974
#define PCIE_PHY_PCS_STATUS2 0x978
#define PCIE_PHY_PCS_STATUS3 0x97C
#define PCIE_PHY_COM_RESET_STATUS 0x980
#define PCIE_PHY_OSC_DTCT_STATUS 0x984
#define PCIE_PHY_REVISION_ID0 0x988
#define PCIE_PHY_REVISION_ID1 0x98C
#define PCIE_PHY_REVISION_ID2 0x990
#define PCIE_PHY_REVISION_ID3 0x994
#define PCIE_PHY_DEBUG_BUS_0_STATUS 0x998
#define PCIE_PHY_DEBUG_BUS_1_STATUS 0x99C
#define PCIE_PHY_DEBUG_BUS_2_STATUS 0x9A0
#define PCIE_PHY_DEBUG_BUS_3_STATUS 0x9A4
#define PCIE_PHY_LP_WAKEUP_DLY_TIME_AUXCLK_MSB 0x9A8
#define PCIE_PHY_OSC_DTCT_ACTIONS 0x9AC
#define PCIE_PHY_SIGDET_CNTRL 0x9B0
#define PCIE_PHY_IDAC_CAL_CNTRL 0x9B4
#define PCIE_PHY_CMN_ACK_OUT_SEL 0x9B8
#define PCIE_PHY_PLL_LOCK_CHK_DLY_TIME_SYSCLK 0x9BC
#define PCIE_PHY_AUTONOMOUS_MODE_STATUS 0x9C0
#define PCIE_PHY_ENDPOINT_REFCLK_CNTRL 0x9C4
#define PCIE_PHY_EPCLK_PRE_PLL_LOCK_DLY_SYSCLK 0x9C8
#define PCIE_PHY_EPCLK_PRE_PLL_LOCK_DLY_AUXCLK 0x9CC
#define PCIE_PHY_EPCLK_DLY_COUNT_VAL_L 0x9D0
#define PCIE_PHY_EPCLK_DLY_COUNT_VAL_H 0x9D4
#define PCIE_PHY_RX_SIGDET_LVL 0x9D8
#define PCIE_PHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x9DC
#define PCIE_PHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x9E0
#define PCIE_PHY_AUTONOMOUS_MODE_CTRL2 0x9E4
#define PCIE_PHY_RXTERMINATION_DLY_SEL 0x9E8
#define PCIE_PHY_LFPS_PER_TIMER_VAL 0x9EC
#define PCIE_PHY_SIGDET_STARTUP_TIMER_VAL 0x9F0
#define PCIE_PHY_LOCK_DETECT_CONFIG4 0x9F4
#endif

332
include/linux/msm_ep_pcie.h Normal file
View file

@ -0,0 +1,332 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015, 2017, 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MSM_EP_PCIE_H
#define __MSM_EP_PCIE_H
#include <linux/types.h>
enum ep_pcie_link_status {
EP_PCIE_LINK_DISABLED,
EP_PCIE_LINK_UP,
EP_PCIE_LINK_ENABLED,
};
enum ep_pcie_event {
EP_PCIE_EVENT_INVALID = 0,
EP_PCIE_EVENT_PM_D0 = 0x1,
EP_PCIE_EVENT_PM_D3_HOT = 0x2,
EP_PCIE_EVENT_PM_D3_COLD = 0x4,
EP_PCIE_EVENT_PM_RST_DEAST = 0x8,
EP_PCIE_EVENT_LINKDOWN = 0x10,
EP_PCIE_EVENT_LINKUP = 0x20,
EP_PCIE_EVENT_MHI_A7 = 0x40,
EP_PCIE_EVENT_MMIO_WRITE = 0x80,
EP_PCIE_EVENT_L1SUB_TIMEOUT = 0x100,
EP_PCIE_EVENT_L1SUB_TIMEOUT_EXIT = 0x200,
};
enum ep_pcie_irq_event {
EP_PCIE_INT_EVT_LINK_DOWN = 1,
EP_PCIE_INT_EVT_BME,
EP_PCIE_INT_EVT_PM_TURNOFF,
EP_PCIE_INT_EVT_DEBUG,
EP_PCIE_INT_EVT_LTR,
EP_PCIE_INT_EVT_MHI_Q6,
EP_PCIE_INT_EVT_MHI_A7,
EP_PCIE_INT_EVT_DSTATE_CHANGE,
EP_PCIE_INT_EVT_L1SUB_TIMEOUT,
EP_PCIE_INT_EVT_MMIO_WRITE,
EP_PCIE_INT_EVT_CFG_WRITE,
EP_PCIE_INT_EVT_BRIDGE_FLUSH_N,
EP_PCIE_INT_EVT_LINK_UP,
EP_PCIE_INT_EVT_EDMA = 22,
EP_PCIE_INT_EVT_MAX = 13,
};
enum ep_pcie_trigger {
EP_PCIE_TRIGGER_CALLBACK,
EP_PCIE_TRIGGER_COMPLETION,
};
enum ep_pcie_options {
EP_PCIE_OPT_NULL = 0,
EP_PCIE_OPT_AST_WAKE = 0x1,
EP_PCIE_OPT_POWER_ON = 0x2,
EP_PCIE_OPT_ENUM = 0x4,
EP_PCIE_OPT_ENUM_ASYNC = 0x8,
EP_PCIE_OPT_ALL = 0xFFFFFFFF,
};
struct ep_pcie_notify {
enum ep_pcie_event event;
void *user;
void *data;
u32 options;
};
struct ep_pcie_register_event {
u32 events;
void *user;
enum ep_pcie_trigger mode;
void (*callback)(struct ep_pcie_notify *notify);
struct ep_pcie_notify notify;
struct completion *completion;
u32 options;
};
struct ep_pcie_iatu {
u32 start;
u32 end;
u32 tgt_lower;
u32 tgt_upper;
};
struct ep_pcie_msi_config {
u32 lower;
u32 upper;
u32 data;
u32 msg_num;
};
struct ep_pcie_db_config {
u8 base;
u8 end;
u32 tgt_addr;
};
struct ep_pcie_inactivity {
bool enable;
uint32_t timer_us;
};
struct ep_pcie_hw {
struct list_head node;
u32 device_id;
void **private_data;
int (*register_event)(struct ep_pcie_register_event *reg);
int (*deregister_event)(void);
enum ep_pcie_link_status (*get_linkstatus)(void);
int (*config_outbound_iatu)(struct ep_pcie_iatu entries[],
u32 num_entries);
int (*get_msi_config)(struct ep_pcie_msi_config *cfg);
int (*trigger_msi)(u32 idx);
int (*wakeup_host)(enum ep_pcie_event event);
int (*enable_endpoint)(enum ep_pcie_options opt);
int (*disable_endpoint)(void);
int (*config_db_routing)(struct ep_pcie_db_config chdb_cfg,
struct ep_pcie_db_config erdb_cfg);
int (*mask_irq_event)(enum ep_pcie_irq_event event,
bool enable);
int (*configure_inactivity_timer)(struct ep_pcie_inactivity *param);
};
/*
* ep_pcie_register_drv - register HW driver.
* @phandle: PCIe endpoint HW driver handle
*
* This function registers PCIe HW driver to PCIe endpoint service
* layer.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_register_drv(struct ep_pcie_hw *phandle);
/*
* ep_pcie_deregister_drv - deregister HW driver.
* @phandle: PCIe endpoint HW driver handle
*
* This function deregisters PCIe HW driver to PCIe endpoint service
* layer.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_deregister_drv(struct ep_pcie_hw *phandle);
/*
* ep_pcie_get_phandle - get PCIe endpoint HW driver handle.
* @id: PCIe endpoint device ID
*
* This function deregisters PCIe HW driver from PCIe endpoint service
* layer.
*
* Return: PCIe endpoint HW driver handle
*/
struct ep_pcie_hw *ep_pcie_get_phandle(u32 id);
/*
* ep_pcie_register_event - register event with PCIe driver.
* @phandle: PCIe endpoint HW driver handle
* @reg: event structure
*
* This function gives PCIe client driver an option to register
* event with PCIe driver.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_register_event(struct ep_pcie_hw *phandle,
struct ep_pcie_register_event *reg);
/*
* ep_pcie_deregister_event - deregister event with PCIe driver.
* @phandle: PCIe endpoint HW driver handle
*
* This function gives PCIe client driver an option to deregister
* existing event with PCIe driver.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_deregister_event(struct ep_pcie_hw *phandle);
/*
* ep_pcie_get_linkstatus - indicate the status of PCIe link.
* @phandle: PCIe endpoint HW driver handle
*
* This function tells PCIe client about the status of PCIe link.
*
* Return: status of PCIe link
*/
enum ep_pcie_link_status ep_pcie_get_linkstatus(struct ep_pcie_hw *phandle);
/*
* ep_pcie_config_outbound_iatu - configure outbound iATU.
* @entries: iatu entries
* @num_entries: number of iatu entries
*
* This function configures the outbound iATU for PCIe
* client's access to the regions in the host memory which
* are specified by the SW on host side.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_config_outbound_iatu(struct ep_pcie_hw *phandle,
struct ep_pcie_iatu entries[],
u32 num_entries);
/*
* ep_pcie_get_msi_config - get MSI config info.
* @phandle: PCIe endpoint HW driver handle
* @cfg: pointer to MSI config
*
* This function returns MSI config info.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_get_msi_config(struct ep_pcie_hw *phandle,
struct ep_pcie_msi_config *cfg);
/*
* ep_pcie_trigger_msi - trigger an MSI.
* @phandle: PCIe endpoint HW driver handle
* @idx: MSI index number
*
* This function allows PCIe client to trigger an MSI
* on host side.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_trigger_msi(struct ep_pcie_hw *phandle, u32 idx);
/*
* ep_pcie_wakeup_host - wake up the host.
* @phandle: PCIe endpoint HW driver handle
* @event: PCIe event of ep_pcie_event type
*
* This function asserts WAKE GPIO to wake up the host.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_wakeup_host(struct ep_pcie_hw *phandle, enum ep_pcie_event event);
/*
* ep_pcie_enable_endpoint - enable PCIe endpoint.
* @phandle: PCIe endpoint HW driver handle
* @opt: endpoint enable options
*
* This function is to enable the PCIe endpoint device.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_enable_endpoint(struct ep_pcie_hw *phandle,
enum ep_pcie_options opt);
/*
* ep_pcie_disable_endpoint - disable PCIe endpoint.
* @phandle: PCIe endpoint HW driver handle
*
* This function is to disable the PCIe endpoint device.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_disable_endpoint(struct ep_pcie_hw *phandle);
/*
* ep_pcie_config_db_routing - Configure routing of doorbells to another block.
* @phandle: PCIe endpoint HW driver handle
* @chdb_cfg: channel doorbell config
* @erdb_cfg: event ring doorbell config
*
* This function allows PCIe core to route the doorbells intended
* for another entity via a target address.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_config_db_routing(struct ep_pcie_hw *phandle,
struct ep_pcie_db_config chdb_cfg,
struct ep_pcie_db_config erdb_cfg);
/*
* ep_pcie_mask_irq_event - enable and disable IRQ event.
* @phandle: PCIe endpoint HW driver handle
* @event: IRQ event
* @enable: true to enable that IRQ event and false to disable
*
* This function is to enable and disable IRQ event.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_mask_irq_event(struct ep_pcie_hw *phandle,
enum ep_pcie_irq_event event,
bool enable);
/*
* ep_pcie_configure_inactivity_timer - Configure timer to trigger
* upon link inactivity.
* @phandle: PCIe endpoint HW driver handle
* @param: structure member to program the timer and enable it.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_configure_inactivity_timer(struct ep_pcie_hw *phandle,
struct ep_pcie_inactivity *param);
/*
* ep_pcie_core_l1ss_sleep_config_enable - Enable L1ss sleep configuration
* to gate the CLKREQ# and disable PCIe resources.
*
* Return: 0 on success, negative value on error
*/
int ep_pcie_core_l1ss_sleep_config_enable(void);
#if IS_ENABLED(CONFIG_QCOM_PCI_EDMA)
int qcom_edma_init(struct device *dev);
void edma_dump(void);
#else
static inline int qcom_edma_init(struct device *dev)
{
return 0;
}
static inline void edma_dump(void) {}
#endif
#endif