msm: ep_pcie: add PCIe endpoint driver
The MSM PCIe endpoint driver enables the PCIe core in endpoint mode and handles the control signaling with PCIe root complex on host side. Change-Id: Ifc2735e061820762c6040eda44089a2dc26fc065 Signed-off-by: Yan He <yanhe@codeaurora.org>
This commit is contained in:
parent
3b1bda734d
commit
5dbc08812b
11 changed files with 3771 additions and 0 deletions
106
Documentation/devicetree/bindings/pci/msm_ep_pcie.txt
Normal file
106
Documentation/devicetree/bindings/pci/msm_ep_pcie.txt
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
MSM PCI express endpoint
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: should be "qcom,pcie-ep".
|
||||||
|
- reg: should contain PCIe register maps.
|
||||||
|
- reg-names: indicates various resources passed to driver by name.
|
||||||
|
Should be "msi", "dm_core", "elbi", "parf", "phy", "mmio".
|
||||||
|
These correspond to different modules within the PCIe domain.
|
||||||
|
- #address-cells: Should provide a value of 0.
|
||||||
|
- interrupt-parent: Should be the PCIe device node itself here.
|
||||||
|
- interrupts: Should be in the format <0 1 2> and it is an index to the
|
||||||
|
interrupt-map that contains PCIe related interrupts.
|
||||||
|
- #interrupt-cells: Should provide a value of 1.
|
||||||
|
- #interrupt-map-mask: should provide a value of 0xffffffff.
|
||||||
|
- interrupt-map: Must create mapping for the number of interrupts
|
||||||
|
that are defined in above interrupts property.
|
||||||
|
For PCIe device node, it should define 6 mappings for
|
||||||
|
the corresponding PCIe interrupts supporting the
|
||||||
|
specification.
|
||||||
|
- interrupt-names: indicates interrupts passed to driver by name.
|
||||||
|
Should be "int_pm_turnoff", "int_dstate_change",
|
||||||
|
"int_l1sub_timeout", "int_link_up",
|
||||||
|
"int_link_down", "int_bridge_flush_n".
|
||||||
|
- perst-gpio: PERST GPIO specified by PCIe spec.
|
||||||
|
- wake-gpio: WAKE GPIO specified by PCIe spec.
|
||||||
|
- clkreq-gpio: CLKREQ GPIO specified by PCIe spec.
|
||||||
|
- <supply-name>-supply: phandle to the regulator device tree node.
|
||||||
|
Refer to the schematics for the corresponding voltage regulators.
|
||||||
|
vreg-1.8-supply: phandle to the analog supply for the PCIe controller.
|
||||||
|
vreg-0.9-supply: phandle to the analog supply for the PCIe controller.
|
||||||
|
|
||||||
|
Optional Properties:
|
||||||
|
- qcom,<supply-name>-voltage-level: specifies voltage levels for supply.
|
||||||
|
Should be specified in pairs (max, min, optimal), units uV.
|
||||||
|
- clock-names: list of names of clock inputs.
|
||||||
|
Should be "pcie_0_pipe_clk",
|
||||||
|
"pcie_0_aux_clk", "pcie_0_cfg_ahb_clk",
|
||||||
|
"pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk",
|
||||||
|
"pcie_0_ldo";
|
||||||
|
- max-clock-frequency-hz: list of the maximum operating frequencies stored
|
||||||
|
in the same order of clock names;
|
||||||
|
- qcom,pcie-phy-ver: version of PCIe PHY.
|
||||||
|
- qcom,pcie-link-speed: generation of PCIe link speed. The value could be
|
||||||
|
1, 2 or 3.
|
||||||
|
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
|
||||||
|
below optional properties:
|
||||||
|
- qcom,msm-bus,name
|
||||||
|
- qcom,msm-bus,num-cases
|
||||||
|
- qcom,msm-bus,num-paths
|
||||||
|
- qcom,msm-bus,vectors-KBps
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
pcie_ep: qcom,pcie@bfffd000 {
|
||||||
|
compatible = "qcom,pcie-ep";
|
||||||
|
|
||||||
|
reg = <0xbfffd000 0x1000>,
|
||||||
|
<0xbfffe000 0x1000>,
|
||||||
|
<0xbffff000 0x1000>,
|
||||||
|
<0xfc520000 0x2000>,
|
||||||
|
<0xfc526000 0x1000>,
|
||||||
|
<0xfc527000 0x1000>;
|
||||||
|
reg-names = "msi", "dm_core", "elbi", "parf", "phy", "mmio";
|
||||||
|
|
||||||
|
#address-cells = <0>;
|
||||||
|
interrupt-parent = <&pcie_ep>;
|
||||||
|
interrupts = <0 1 2 3 4 5>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
interrupt-map-mask = <0xffffffff>;
|
||||||
|
interrupt-map = <0 &intc 0 44 0
|
||||||
|
1 &intc 0 46 0
|
||||||
|
2 &intc 0 47 0
|
||||||
|
3 &intc 0 50 0
|
||||||
|
4 &intc 0 51 0
|
||||||
|
5 &intc 0 52 0>;
|
||||||
|
interrupt-names = "int_pm_turnoff", "int_dstate_change",
|
||||||
|
"int_l1sub_timeout", "int_link_up",
|
||||||
|
"int_link_down", "int_bridge_flush_n";
|
||||||
|
|
||||||
|
perst-gpio = <&msmgpio 65 0>;
|
||||||
|
wake-gpio = <&msmgpio 61 0>;
|
||||||
|
clkreq-gpio = <&msmgpio 64 0>;
|
||||||
|
|
||||||
|
gdsc-vdd-supply = <&gdsc_pcie_0>;
|
||||||
|
vreg-1.8-supply = <&pmd9635_l8>;
|
||||||
|
vreg-0.9-supply = <&pmd9635_l4>;
|
||||||
|
|
||||||
|
qcom,vreg-1.8-voltage-level = <1800000 1800000 1000>;
|
||||||
|
qcom,vreg-0.9-voltage-level = <950000 950000 24000>;
|
||||||
|
|
||||||
|
clock-names = "pcie_0_pipe_clk",
|
||||||
|
"pcie_0_aux_clk", "pcie_0_cfg_ahb_clk",
|
||||||
|
"pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk",
|
||||||
|
"pcie_0_ldo";
|
||||||
|
max-clock-frequency-hz = <62500000>, <1000000>,
|
||||||
|
<0>, <0>, <0>, <0>;
|
||||||
|
|
||||||
|
qcom,msm-bus,name = "pcie-ep";
|
||||||
|
qcom,msm-bus,num-cases = <2>;
|
||||||
|
qcom,msm-bus,num-paths = <1>;
|
||||||
|
qcom,msm-bus,vectors-KBps =
|
||||||
|
<45 512 0 0>,
|
||||||
|
<45 512 500 800>;
|
||||||
|
|
||||||
|
qcom,pcie-link-speed = <1>;
|
||||||
|
};
|
|
@ -48,6 +48,27 @@ config SPS_SUPPORT_NDP_BAM
|
||||||
help
|
help
|
||||||
No-Data-Path BAM is used to improve BAM performance.
|
No-Data-Path BAM is used to improve BAM performance.
|
||||||
|
|
||||||
|
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 GPIO_USB_DETECT
|
config GPIO_USB_DETECT
|
||||||
tristate "GPIO-based USB VBUS Detection"
|
tristate "GPIO-based USB VBUS Detection"
|
||||||
depends on POWER_SUPPLY
|
depends on POWER_SUPPLY
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
|
obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
|
||||||
obj-$(CONFIG_QPNP_COINCELL) += qpnp-coincell.o
|
obj-$(CONFIG_QPNP_COINCELL) += qpnp-coincell.o
|
||||||
obj-$(CONFIG_SPS) += sps/
|
obj-$(CONFIG_SPS) += sps/
|
||||||
|
obj-$(CONFIG_EP_PCIE) += ep_pcie/
|
||||||
obj-$(CONFIG_GPIO_USB_DETECT) += gpio-usbdetect.o
|
obj-$(CONFIG_GPIO_USB_DETECT) += gpio-usbdetect.o
|
||||||
|
|
3
drivers/platform/msm/ep_pcie/Makefile
Normal file
3
drivers/platform/msm/ep_pcie/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
obj-$(CONFIG_EP_PCIE) += ep_pcie.o
|
||||||
|
obj-$(CONFIG_EP_PCIE_HW) += ep_pcie_core.o ep_pcie_phy.o ep_pcie_dbg.o
|
||||||
|
|
232
drivers/platform/msm/ep_pcie/ep_pcie.c
Normal file
232
drivers/platform/msm/ep_pcie/ep_pcie.c
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
/* Copyright (c) 2015, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 <linux/msm_ep_pcie.h>
|
||||||
|
|
||||||
|
LIST_HEAD(head);
|
||||||
|
|
||||||
|
int ep_pcie_register_drv(struct ep_pcie_hw *handle)
|
||||||
|
{
|
||||||
|
struct ep_pcie_hw *present;
|
||||||
|
bool new = true;
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
pr_err("ep_pcie:%s: the input handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
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.",
|
||||||
|
__func__, handle->device_id);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
pr_debug(
|
||||||
|
"ep_pcie:%s: driver to register for device 0x%x has already existed.",
|
||||||
|
__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 (!handle) {
|
||||||
|
pr_err("ep_pcie:%s: the input handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
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.",
|
||||||
|
__func__, handle->device_id);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: driver for device 0x%x does not exist.",
|
||||||
|
__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.",
|
||||||
|
__func__, id);
|
||||||
|
return present;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_debug("ep_pcie:%s: driver for device 0x%x does not exist.",
|
||||||
|
__func__, id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_get_phandle);
|
||||||
|
|
||||||
|
int ep_pcie_register_event(struct ep_pcie_hw *phandle,
|
||||||
|
struct ep_pcie_register_event *reg)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->register_event(reg);
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_register_event);
|
||||||
|
|
||||||
|
int ep_pcie_deregister_event(struct ep_pcie_hw *phandle)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->deregister_event();
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_deregister_event);
|
||||||
|
|
||||||
|
enum ep_pcie_link_status ep_pcie_get_linkstatus(struct ep_pcie_hw *phandle)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->get_linkstatus();
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 (phandle) {
|
||||||
|
return phandle->config_outbound_iatu(entries, num_entries);
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 (phandle) {
|
||||||
|
return phandle->get_msi_config(cfg);
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_get_msi_config);
|
||||||
|
|
||||||
|
int ep_pcie_trigger_msi(struct ep_pcie_hw *phandle, u32 idx)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->trigger_msi(idx);
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_trigger_msi);
|
||||||
|
|
||||||
|
int ep_pcie_wakeup_host(struct ep_pcie_hw *phandle)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->wakeup_host();
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 (phandle) {
|
||||||
|
return phandle->config_db_routing(chdb_cfg, erdb_cfg);
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_config_db_routing);
|
||||||
|
|
||||||
|
int ep_pcie_enable_endpoint(struct ep_pcie_hw *phandle,
|
||||||
|
enum ep_pcie_options opt)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->enable_endpoint(opt);
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_enable_endpoint);
|
||||||
|
|
||||||
|
int ep_pcie_disable_endpoint(struct ep_pcie_hw *phandle)
|
||||||
|
{
|
||||||
|
if (phandle) {
|
||||||
|
return phandle->disable_endpoint();
|
||||||
|
} else {
|
||||||
|
pr_err("ep_pcie:%s: the input driver handle is NULL.",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep_pcie_disable_endpoint);
|
332
drivers/platform/msm/ep_pcie/ep_pcie_com.h
Normal file
332
drivers/platform/msm/ep_pcie/ep_pcie_com.h
Normal file
|
@ -0,0 +1,332 @@
|
||||||
|
/* Copyright (c) 2015, 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 __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/msm_ep_pcie.h>
|
||||||
|
|
||||||
|
#define PCIE20_PARF_SYS_CTRL 0x00
|
||||||
|
#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_DBI_BASE_ADDR 0x168
|
||||||
|
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C
|
||||||
|
#define PCIE20_PARF_MHI_BASE_ADDR_LOWER 0x178
|
||||||
|
#define PCIE20_PARF_MHI_BASE_ADDR_UPPER 0x17c
|
||||||
|
#define PCIE20_PARF_DEBUG_INT_EN 0x190
|
||||||
|
#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_DEVICE_TYPE 0x1000
|
||||||
|
|
||||||
|
#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_COMMAND_STATUS 0x04
|
||||||
|
#define PCIE20_CLASS_CODE_REVISION_ID 0x08
|
||||||
|
#define PCIE20_BIST_HDR_TYPE 0x0C
|
||||||
|
#define PCIE20_BAR0 0x10
|
||||||
|
#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_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_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 PERST_TIMEOUT_US_MIN 5000
|
||||||
|
#define PERST_TIMEOUT_US_MAX 5100
|
||||||
|
#define PERST_CHECK_MAX_COUNT 2000
|
||||||
|
#define LINK_UP_TIMEOUT_US_MIN 5000
|
||||||
|
#define LINK_UP_TIMEOUT_US_MAX 5100
|
||||||
|
#define LINK_UP_CHECK_MAX_COUNT 2000
|
||||||
|
#define BME_TIMEOUT_US_MIN 5000
|
||||||
|
#define BME_TIMEOUT_US_MAX 5100
|
||||||
|
#define BME_CHECK_MAX_COUNT 6000
|
||||||
|
#define PHY_STABILIZATION_DELAY_US_MIN 995
|
||||||
|
#define PHY_STABILIZATION_DELAY_US_MAX 1005
|
||||||
|
#define REFCLK_STABILIZATION_DELAY_US_MIN 995
|
||||||
|
#define REFCLK_STABILIZATION_DELAY_US_MAX 1005
|
||||||
|
#define PHY_READY_TIMEOUT_COUNT 10000
|
||||||
|
#define XMLH_LINK_UP 0x400
|
||||||
|
|
||||||
|
#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 2
|
||||||
|
#define EP_PCIE_MAX_CLK 5
|
||||||
|
#define EP_PCIE_MAX_PIPE_CLK 1
|
||||||
|
|
||||||
|
#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_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 { \
|
||||||
|
if ((dev)->ipc_log_sel) \
|
||||||
|
ipc_log_string((dev)->ipc_log_sel, \
|
||||||
|
"DBG1:%s: " fmt, __func__, arg); \
|
||||||
|
if ((dev)->ipc_log_ful) \
|
||||||
|
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 { \
|
||||||
|
if ((dev)->ipc_log_ful) \
|
||||||
|
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 { \
|
||||||
|
if ((dev)->ipc_log_dump) \
|
||||||
|
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 { \
|
||||||
|
if ((dev)->ipc_log_sel) \
|
||||||
|
ipc_log_string((dev)->ipc_log_sel, \
|
||||||
|
"INFO:%s: " fmt, __func__, arg); \
|
||||||
|
if ((dev)->ipc_log_ful) \
|
||||||
|
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 { \
|
||||||
|
if ((dev)->ipc_log_sel) \
|
||||||
|
ipc_log_string((dev)->ipc_log_sel, \
|
||||||
|
"ERR:%s: " fmt, __func__, arg); \
|
||||||
|
if ((dev)->ipc_log_ful) \
|
||||||
|
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_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_MAX_IRQ,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ep_pcie_gpio {
|
||||||
|
EP_PCIE_GPIO_PERST,
|
||||||
|
EP_PCIE_GPIO_WAKE,
|
||||||
|
EP_PCIE_GPIO_CLKREQ,
|
||||||
|
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_res_info_t {
|
||||||
|
char *name;
|
||||||
|
struct resource *resource;
|
||||||
|
void __iomem *base;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ep_pcie_irq_info_t {
|
||||||
|
char *name;
|
||||||
|
u32 num;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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_irq_info_t irq[EP_PCIE_MAX_IRQ];
|
||||||
|
struct ep_pcie_res_info_t res[EP_PCIE_MAX_RES];
|
||||||
|
|
||||||
|
void __iomem *parf;
|
||||||
|
void __iomem *phy;
|
||||||
|
void __iomem *mmio;
|
||||||
|
void __iomem *msi;
|
||||||
|
void __iomem *dm_core;
|
||||||
|
void __iomem *elbi;
|
||||||
|
|
||||||
|
struct msm_bus_scale_pdata *bus_scale_table;
|
||||||
|
u32 bus_client;
|
||||||
|
u32 link_speed;
|
||||||
|
|
||||||
|
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 pm_to_counter;
|
||||||
|
ulong d0_counter;
|
||||||
|
ulong d3_counter;
|
||||||
|
ulong perst_ast_counter;
|
||||||
|
ulong perst_deast_counter;
|
||||||
|
ulong wake_counter;
|
||||||
|
ulong msi_counter;
|
||||||
|
|
||||||
|
bool dump_conf;
|
||||||
|
|
||||||
|
bool enumerated;
|
||||||
|
enum ep_pcie_link_status link_status;
|
||||||
|
bool perst_deast;
|
||||||
|
bool power_on;
|
||||||
|
bool suspending;
|
||||||
|
bool l1ss_enabled;
|
||||||
|
struct ep_pcie_msi_config msi_cfg;
|
||||||
|
|
||||||
|
struct ep_pcie_register_event *event_reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct ep_pcie_dev_t ep_pcie_dev;
|
||||||
|
|
||||||
|
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 *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 *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_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
|
1924
drivers/platform/msm/ep_pcie/ep_pcie_core.c
Normal file
1924
drivers/platform/msm/ep_pcie/ep_pcie_core.c
Normal file
File diff suppressed because it is too large
Load diff
466
drivers/platform/msm/ep_pcie/ep_pcie_dbg.c
Normal file
466
drivers/platform/msm/ep_pcie/ep_pcie_dbg.c
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
/* Copyright (c) 2015, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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_pcie_phy_dump(struct ep_pcie_dev_t *dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int control_offset[6] = {0x60, 0x70, 0x80, 0xA0, 0xB0, 0xB0};
|
||||||
|
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PHY testbus\n", dev->rev);
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
switch (i) {
|
||||||
|
case 3:
|
||||||
|
ep_pcie_write_reg(dev->phy,
|
||||||
|
QSERDES_COM_ATB_SEL2,
|
||||||
|
0x10);
|
||||||
|
EP_PCIE_DUMP(dev,
|
||||||
|
"PCIe V%d: QSERDES_COM_ATB_SEL2: 0x%x\n",
|
||||||
|
dev->rev,
|
||||||
|
readl_relaxed(dev->phy + QSERDES_COM_ATB_SEL2));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ep_pcie_write_reg(dev->phy,
|
||||||
|
QSERDES_TX_SERDES_BYP_EN_OUT,
|
||||||
|
0x10);
|
||||||
|
EP_PCIE_DUMP(dev,
|
||||||
|
"PCIe V%d: QSERDES_TX_SERDES_BYP_EN_OUT: 0x%x\n",
|
||||||
|
dev->rev,
|
||||||
|
readl_relaxed(dev->phy +
|
||||||
|
QSERDES_TX_SERDES_BYP_EN_OUT));
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ep_pcie_write_reg(dev->phy,
|
||||||
|
QSERDES_TX_SERDES_BYP_EN_OUT,
|
||||||
|
0x30);
|
||||||
|
EP_PCIE_DUMP(dev,
|
||||||
|
"PCIe V%d: QSERDES_TX_SERDES_BYP_EN_OUT: 0x%x\n",
|
||||||
|
dev->rev,
|
||||||
|
readl_relaxed(dev->phy +
|
||||||
|
QSERDES_TX_SERDES_BYP_EN_OUT));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_TEST_CONTROL,
|
||||||
|
control_offset[i]);
|
||||||
|
|
||||||
|
EP_PCIE_DUMP(dev,
|
||||||
|
"PCIe V%d: PCIE_PHY_TEST_CONTROL: 0x%x\n",
|
||||||
|
dev->rev,
|
||||||
|
readl_relaxed(dev->phy + PCIE_PHY_TEST_CONTROL));
|
||||||
|
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",
|
||||||
|
dev->rev,
|
||||||
|
readl_relaxed(dev->phy + PCIE_PHY_DEBUG_BUS_3_STATUS));
|
||||||
|
}
|
||||||
|
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PHY register dump\n", dev->rev);
|
||||||
|
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_COM_PLL_VCO_HIGH: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_COM_PLL_VCO_HIGH));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_COM_RESET_SM: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_COM_RESET_SM));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_COM_MUXVAL: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_COM_MUXVAL));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_PI_CTRL1: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_PI_CTRL1));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_PI_CTRL2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_PI_CTRL2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_PI_QUAD: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_PI_QUAD));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_IDATA1: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_IDATA1));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_IDATA2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_IDATA2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_AUX_DATA1: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_AUX_DATA1));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_AUX_DATA2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_AUX_DATA2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_AC_JTAG_OUTP: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_AC_JTAG_OUTP));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_AC_JTAG_OUTN: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_AC_JTAG_OUTN));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_RX_SIGDET: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_RX_SIGDET));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_RX_VDCOFF: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_RX_VDCOFF));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_IDAC_CAL_ON: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_IDAC_CAL_ON));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_IDAC_STATUS_I: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_IDAC_STATUS_I));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_IDAC_STATUS_Q: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_IDAC_STATUS_Q));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_IDAC_STATUS_A: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_IDAC_STATUS_A));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_CALST_STATUS_I: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_CALST_STATUS_I));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_CALST_STATUS_Q: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_CALST_STATUS_Q));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_CALST_STATUS_A: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_CALST_STATUS_A));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS0: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS0));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS1: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS1));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS3: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS3));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS4: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS4));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS5: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS5));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS6: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS6));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS7: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS7));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS8: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS8));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_EOM_STATUS9: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_EOM_STATUS9));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_RX_ALOG_INTF_OBSV: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_RX_ALOG_INTF_OBSV));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_READ_EQCODE: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_READ_EQCODE));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_RX_READ_OFFSETCODE: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_RX_READ_OFFSETCODE));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_TX_BIST_STATUS: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_TX_BIST_STATUS));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_TX_BIST_ERROR_COUNT1: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_TX_BIST_ERROR_COUNT1));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_TX_BIST_ERROR_COUNT2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_TX_BIST_ERROR_COUNT2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_TX_TX_ALOG_INTF_OBSV: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_TX_TX_ALOG_INTF_OBSV));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: QSERDES_TX_PWM_DEC_STATUS: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + QSERDES_TX_PWM_DEC_STATUS));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_BIST_CHK_ERR_CNT_L: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_BIST_CHK_ERR_CNT_L));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_BIST_CHK_ERR_CNT_H: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_BIST_CHK_ERR_CNT_H));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_BIST_CHK_STATUS: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_BIST_CHK_STATUS));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_LFPS_RXTERM_IRQ_SOURCE: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_LFPS_RXTERM_IRQ_SOURCE));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_PCS_STATUS: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_PCS_STATUS));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_PCS_STATUS2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_PCS_STATUS2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_REVISION_ID0: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_REVISION_ID0));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_REVISION_ID1: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_REVISION_ID1));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_REVISION_ID2: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_REVISION_ID2));
|
||||||
|
EP_PCIE_DUMP(dev, "PCIe V%d: PCIE_PHY_REVISION_ID3: 0x%x\n",
|
||||||
|
dev->rev, readl_relaxed(dev->phy + PCIE_PHY_REVISION_ID3));
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
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("bus_client: %d\n",
|
||||||
|
dev->bus_client);
|
||||||
|
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;
|
||||||
|
u32 device_id = 0;
|
||||||
|
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};
|
||||||
|
|
||||||
|
if (dev->power_on) {
|
||||||
|
device_id = readl_relaxed(dev->dm_core);
|
||||||
|
phandle = ep_pcie_get_phandle(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);
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
}
|
81
drivers/platform/msm/ep_pcie/ep_pcie_phy.c
Normal file
81
drivers/platform/msm/ep_pcie/ep_pcie_phy.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/* Copyright (c) 2015, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
EP_PCIE_DBG(dev,
|
||||||
|
"PCIe V%d: PHY V%d: Initializing 20nm QMP phy - 100MHz\n",
|
||||||
|
dev->rev, dev->phy_rev);
|
||||||
|
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_POWER_DOWN_CONTROL, 0x01);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_SYS_CLK_CTRL, 0x1E);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_CP_SETI, 0x11);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_IP_SETP, 0x3F);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_CP_SETP, 0x00);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_IP_SETI, 0x3F);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_IP_TRIM, 0x0F);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_RESETSM_CNTRL, 0x90);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_RES_CODE_CAL_CSR, 0x77);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_RES_TRIM_CONTROL, 0x15);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_TX_RCV_DETECT_LVL, 0x03);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQ_GAIN2_MSB, 0x00);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_SIGDET_ENABLES, 0x40);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_SIGDET_CNTRL, 0x70);
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_PWRUP_RESET_DLY_TIME_SYSCLK, 0xC8);
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_POWER_STATE_CONFIG1, 0xA3);
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_POWER_STATE_CONFIG2, 0x1B);
|
||||||
|
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_VCOTAIL_EN, 0xE1);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_RESETSM_CNTRL2, 0x07);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_IE_TRIM, 0x3F);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_CNTRL, 0x46);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLLLOCK_CMP2, 0x05);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLLLOCK_CMP_EN, 0x03);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_DEC_START1, 0x99);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_CDR_CONTROL1, 0xF5);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_CDR_CONTROL_HALF, 0x2C);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_RES_CODE_START_SEG1, 0x24);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQ_GAIN1_MSB, 0x07);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1E);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1,
|
||||||
|
0x67);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x0C);
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x80);
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_RX_IDLE_DTCT_CNTRL, 0x4D);
|
||||||
|
|
||||||
|
if (dev->phy_rev == 1) {
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_RX_RX_RCVR_IQ_EN, 0x31);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_RESETSM_CNTRL2, 0x5);
|
||||||
|
ep_pcie_write_reg(dev->phy, QSERDES_COM_PLL_VCOTAIL_EN, 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_SW_RESET, 0x00);
|
||||||
|
ep_pcie_write_reg(dev->phy, PCIE_PHY_START, 0x03);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ep_pcie_phy_is_ready(struct ep_pcie_dev_t *dev)
|
||||||
|
{
|
||||||
|
if (readl_relaxed(dev->phy + PCIE_PHY_PCS_STATUS) & BIT(6))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
351
drivers/platform/msm/ep_pcie/ep_pcie_phy.h
Normal file
351
drivers/platform/msm/ep_pcie/ep_pcie_phy.h
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
/* Copyright (c) 2015, 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 __EP_PCIE_PHY_H
|
||||||
|
#define __EP_PCIE_PHY_H
|
||||||
|
|
||||||
|
#define QSERDES_COM_SYS_CLK_CTRL 0x0
|
||||||
|
#define QSERDES_COM_PLL_VCOTAIL_EN 0x4
|
||||||
|
#define QSERDES_COM_CMN_MODE 0x8
|
||||||
|
#define QSERDES_COM_IE_TRIM 0xC
|
||||||
|
#define QSERDES_COM_IP_TRIM 0x10
|
||||||
|
#define QSERDES_COM_PLL_CNTRL 0x14
|
||||||
|
#define QSERDES_COM_PLL_PHSEL_CONTROL 0x18
|
||||||
|
#define QSERDES_COM_IPTAT_TRIM_VCCA_TX_SEL 0x1C
|
||||||
|
#define QSERDES_COM_PLL_PHSEL_DC 0x20
|
||||||
|
#define QSERDES_COM_PLL_IP_SETI 0x24
|
||||||
|
#define QSERDES_COM_CORE_CLK_IN_SYNC_SEL 0x28
|
||||||
|
#define QSERDES_COM_PLL_BKG_KVCO_CAL_EN 0x2C
|
||||||
|
#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x30
|
||||||
|
#define QSERDES_COM_PLL_CP_SETI 0x34
|
||||||
|
#define QSERDES_COM_PLL_IP_SETP 0x38
|
||||||
|
#define QSERDES_COM_PLL_CP_SETP 0x3C
|
||||||
|
#define QSERDES_COM_ATB_SEL1 0x40
|
||||||
|
#define QSERDES_COM_ATB_SEL2 0x44
|
||||||
|
#define QSERDES_COM_SYSCLK_EN_SEL_TXBAND 0x48
|
||||||
|
#define QSERDES_COM_RESETSM_CNTRL 0x4C
|
||||||
|
#define QSERDES_COM_RESETSM_CNTRL2 0x50
|
||||||
|
#define QSERDES_COM_RESETSM_CNTRL3 0x54
|
||||||
|
#define QSERDES_COM_DIV_REF1 0x58
|
||||||
|
#define QSERDES_COM_DIV_REF2 0x5C
|
||||||
|
#define QSERDES_COM_KVCO_COUNT1 0x60
|
||||||
|
#define QSERDES_COM_KVCO_COUNT2 0x64
|
||||||
|
#define QSERDES_COM_KVCO_CAL_CNTRL 0x68
|
||||||
|
#define QSERDES_COM_KVCO_CODE 0x6C
|
||||||
|
#define QSERDES_COM_VREF_CFG1 0x70
|
||||||
|
#define QSERDES_COM_VREF_CFG2 0x74
|
||||||
|
#define QSERDES_COM_VREF_CFG3 0x78
|
||||||
|
#define QSERDES_COM_VREF_CFG4 0x7C
|
||||||
|
#define QSERDES_COM_VREF_CFG5 0x80
|
||||||
|
#define QSERDES_COM_VREF_CFG6 0x84
|
||||||
|
#define QSERDES_COM_PLLLOCK_CMP1 0x88
|
||||||
|
#define QSERDES_COM_PLLLOCK_CMP2 0x8C
|
||||||
|
#define QSERDES_COM_PLLLOCK_CMP3 0x90
|
||||||
|
#define QSERDES_COM_PLLLOCK_CMP_EN 0x94
|
||||||
|
#define QSERDES_COM_BGTC 0x98
|
||||||
|
#define QSERDES_COM_PLL_TEST_UPDN 0x9C
|
||||||
|
#define QSERDES_COM_PLL_VCO_TUNE 0xA0
|
||||||
|
#define QSERDES_COM_DEC_START1 0xA4
|
||||||
|
#define QSERDES_COM_PLL_AMP_OS 0xA8
|
||||||
|
#define QSERDES_COM_SSC_EN_CENTER 0xAC
|
||||||
|
#define QSERDES_COM_SSC_ADJ_PER1 0xB0
|
||||||
|
#define QSERDES_COM_SSC_ADJ_PER2 0xB4
|
||||||
|
#define QSERDES_COM_SSC_PER1 0xB8
|
||||||
|
#define QSERDES_COM_SSC_PER2 0xBC
|
||||||
|
#define QSERDES_COM_SSC_STEP_SIZE1 0xC0
|
||||||
|
#define QSERDES_COM_SSC_STEP_SIZE2 0xC4
|
||||||
|
#define QSERDES_COM_RES_CODE_UP 0xC8
|
||||||
|
#define QSERDES_COM_RES_CODE_DN 0xCC
|
||||||
|
#define QSERDES_COM_RES_CODE_UP_OFFSET 0xD0
|
||||||
|
#define QSERDES_COM_RES_CODE_DN_OFFSET 0xD4
|
||||||
|
#define QSERDES_COM_RES_CODE_START_SEG1 0xD8
|
||||||
|
#define QSERDES_COM_RES_CODE_START_SEG2 0xDC
|
||||||
|
#define QSERDES_COM_RES_CODE_CAL_CSR 0xE0
|
||||||
|
#define QSERDES_COM_RES_CODE 0xE4
|
||||||
|
#define QSERDES_COM_RES_TRIM_CONTROL 0xE8
|
||||||
|
#define QSERDES_COM_RES_TRIM_CONTROL2 0xEC
|
||||||
|
#define QSERDES_COM_RES_TRIM_EN_VCOCALDONE 0xF0
|
||||||
|
#define QSERDES_COM_FAUX_EN 0xF4
|
||||||
|
#define QSERDES_COM_DIV_FRAC_START1 0xF8
|
||||||
|
#define QSERDES_COM_DIV_FRAC_START2 0xFC
|
||||||
|
#define QSERDES_COM_DIV_FRAC_START3 0x100
|
||||||
|
#define QSERDES_COM_DEC_START2 0x104
|
||||||
|
#define QSERDES_COM_PLL_RXTXEPCLK_EN 0x108
|
||||||
|
#define QSERDES_COM_PLL_CRCTRL 0x10C
|
||||||
|
#define QSERDES_COM_PLL_CLKEPDIV 0x110
|
||||||
|
#define QSERDES_COM_PLL_FREQUPDATE 0x114
|
||||||
|
#define QSERDES_COM_PLL_BKGCAL_TRIM_UP 0x118
|
||||||
|
#define QSERDES_COM_PLL_BKGCAL_TRIM_DN 0x11C
|
||||||
|
#define QSERDES_COM_PLL_BKGCAL_TRIM_MUX 0x120
|
||||||
|
#define QSERDES_COM_PLL_BKGCAL_VREF_CFG 0x124
|
||||||
|
#define QSERDES_COM_PLL_BKGCAL_DIV_REF1 0x128
|
||||||
|
#define QSERDES_COM_PLL_BKGCAL_DIV_REF2 0x12C
|
||||||
|
#define QSERDES_COM_MUXADDR 0x130
|
||||||
|
#define QSERDES_COM_LOW_POWER_RO_CONTROL 0x134
|
||||||
|
#define QSERDES_COM_POST_DIVIDER_CONTROL 0x138
|
||||||
|
#define QSERDES_COM_HR_OCLK2_DIVIDER 0x13C
|
||||||
|
#define QSERDES_COM_HR_OCLK3_DIVIDER 0x140
|
||||||
|
#define QSERDES_COM_PLL_VCO_HIGH 0x144
|
||||||
|
#define QSERDES_COM_RESET_SM 0x148
|
||||||
|
#define QSERDES_COM_MUXVAL 0x14C
|
||||||
|
#define QSERDES_TX_BIST_MODE_LANENO 0x200
|
||||||
|
#define QSERDES_TX_CLKBUF_ENABLE 0x204
|
||||||
|
#define QSERDES_TX_TX_EMP_POST1_LVL 0x208
|
||||||
|
#define QSERDES_TX_TX_DRV_LVL 0x20C
|
||||||
|
#define QSERDES_TX_RESET_TSYNC_EN 0x210
|
||||||
|
#define QSERDES_TX_LPB_EN 0x214
|
||||||
|
#define QSERDES_TX_RES_CODE_UP 0x218
|
||||||
|
#define QSERDES_TX_RES_CODE_DN 0x21C
|
||||||
|
#define QSERDES_TX_PERL_LENGTH1 0x220
|
||||||
|
#define QSERDES_TX_PERL_LENGTH2 0x224
|
||||||
|
#define QSERDES_TX_SERDES_BYP_EN_OUT 0x228
|
||||||
|
#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x22C
|
||||||
|
#define QSERDES_TX_PARRATE_REC_DETECT_IDLE_EN 0x230
|
||||||
|
#define QSERDES_TX_BIST_PATTERN1 0x234
|
||||||
|
#define QSERDES_TX_BIST_PATTERN2 0x238
|
||||||
|
#define QSERDES_TX_BIST_PATTERN3 0x23C
|
||||||
|
#define QSERDES_TX_BIST_PATTERN4 0x240
|
||||||
|
#define QSERDES_TX_BIST_PATTERN5 0x244
|
||||||
|
#define QSERDES_TX_BIST_PATTERN6 0x248
|
||||||
|
#define QSERDES_TX_BIST_PATTERN7 0x24C
|
||||||
|
#define QSERDES_TX_BIST_PATTERN8 0x250
|
||||||
|
#define QSERDES_TX_LANE_MODE 0x254
|
||||||
|
#define QSERDES_TX_IDAC_CAL_LANE_MODE 0x258
|
||||||
|
#define QSERDES_TX_IDAC_CAL_LANE_MODE_CONFIGURATION 0x25C
|
||||||
|
#define QSERDES_TX_ATB_SEL1 0x260
|
||||||
|
#define QSERDES_TX_ATB_SEL2 0x264
|
||||||
|
#define QSERDES_TX_RCV_DETECT_LVL 0x268
|
||||||
|
#define QSERDES_TX_PRBS_SEED1 0x26C
|
||||||
|
#define QSERDES_TX_PRBS_SEED2 0x270
|
||||||
|
#define QSERDES_TX_PRBS_SEED3 0x274
|
||||||
|
#define QSERDES_TX_PRBS_SEED4 0x278
|
||||||
|
#define QSERDES_TX_RESET_GEN 0x27C
|
||||||
|
#define QSERDES_TX_TRAN_DRVR_EMP_EN 0x280
|
||||||
|
#define QSERDES_TX_TX_INTERFACE_MODE 0x284
|
||||||
|
#define QSERDES_TX_PWM_CTRL 0x288
|
||||||
|
#define QSERDES_TX_PWM_DATA 0x28C
|
||||||
|
#define QSERDES_TX_PWM_ENC_DIV_CTRL 0x290
|
||||||
|
#define QSERDES_TX_VMODE_CTRL1 0x294
|
||||||
|
#define QSERDES_TX_VMODE_CTRL2 0x298
|
||||||
|
#define QSERDES_TX_VMODE_CTRL3 0x29C
|
||||||
|
#define QSERDES_TX_VMODE_CTRL4 0x2A0
|
||||||
|
#define QSERDES_TX_VMODE_CTRL5 0x2A4
|
||||||
|
#define QSERDES_TX_VMODE_CTRL6 0x2A8
|
||||||
|
#define QSERDES_TX_VMODE_CTRL7 0x2AC
|
||||||
|
#define QSERDES_TX_TX_ALOG_INTF_OBSV_CNTL 0x2B0
|
||||||
|
#define QSERDES_TX_BIST_STATUS 0x2B4
|
||||||
|
#define QSERDES_TX_BIST_ERROR_COUNT1 0x2B8
|
||||||
|
#define QSERDES_TX_BIST_ERROR_COUNT2 0x2BC
|
||||||
|
#define QSERDES_TX_TX_ALOG_INTF_OBSV 0x2C0
|
||||||
|
#define QSERDES_TX_PWM_DEC_STATUS 0x2C4
|
||||||
|
#define QSERDES_RX_CDR_CONTROL1 0x400
|
||||||
|
#define QSERDES_RX_CDR_CONTROL2 0x404
|
||||||
|
#define QSERDES_RX_CDR_CONTROL_HALF 0x408
|
||||||
|
#define QSERDES_RX_CDR_CONTROL_QUARTER 0x40C
|
||||||
|
#define QSERDES_RX_CDR_CONTROL_EIGHTH 0x410
|
||||||
|
#define QSERDES_RX_UCDR_FO_GAIN 0x414
|
||||||
|
#define QSERDES_RX_UCDR_SO_GAIN 0x418
|
||||||
|
#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x41C
|
||||||
|
#define QSERDES_RX_UCDR_FO_TO_SO_DELAY 0x420
|
||||||
|
#define QSERDES_RX_AUX_CONTROL 0x424
|
||||||
|
#define QSERDES_RX_AUX_DATA_TCOARSE 0x428
|
||||||
|
#define QSERDES_RX_AUX_DATA_TFINE_LSB 0x42C
|
||||||
|
#define QSERDES_RX_AUX_DATA_TFINE_MSB 0x430
|
||||||
|
#define QSERDES_RX_RCLK_AUXDATA_SEL 0x434
|
||||||
|
#define QSERDES_RX_AC_JTAG_ENABLE 0x438
|
||||||
|
#define QSERDES_RX_AC_JTAG_INITP 0x43C
|
||||||
|
#define QSERDES_RX_AC_JTAG_INITN 0x440
|
||||||
|
#define QSERDES_RX_AC_JTAG_LVL 0x444
|
||||||
|
#define QSERDES_RX_AC_JTAG_MODE 0x448
|
||||||
|
#define QSERDES_RX_AC_JTAG_RESET 0x44C
|
||||||
|
#define QSERDES_RX_RX_RCVR_IQ_EN 0x450
|
||||||
|
#define QSERDES_RX_RX_IDAC_I_DC_OFFSETS 0x454
|
||||||
|
#define QSERDES_RX_RX_IDAC_Q_DC_OFFSETS 0x458
|
||||||
|
#define QSERDES_RX_RX_IDAC_A_DC_OFFSETS 0x45C
|
||||||
|
#define QSERDES_RX_RX_IDAC_EN 0x460
|
||||||
|
#define QSERDES_RX_RX_IDAC_CTRL0 0x464
|
||||||
|
#define QSERDES_RX_RX_IDAC_CTRL1 0x468
|
||||||
|
#define QSERDES_RX_RX_EOM_EN 0x46C
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL0 0x470
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL1 0x474
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL2 0x478
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL3 0x47C
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL4 0x480
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL5 0x484
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL6 0x488
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL7 0x48C
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL8 0x490
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL9 0x494
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL10 0x498
|
||||||
|
#define QSERDES_RX_RX_EOM_CTRL11 0x49C
|
||||||
|
#define QSERDES_RX_RX_HIGHZ_HIGHRATE 0x4A0
|
||||||
|
#define QSERDES_RX_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x4A4
|
||||||
|
#define QSERDES_RX_RX_EQ_GAIN1_LSB 0x4A8
|
||||||
|
#define QSERDES_RX_RX_EQ_GAIN1_MSB 0x4AC
|
||||||
|
#define QSERDES_RX_RX_EQ_GAIN2_LSB 0x4B0
|
||||||
|
#define QSERDES_RX_RX_EQ_GAIN2_MSB 0x4B4
|
||||||
|
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1 0x4B8
|
||||||
|
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x4BC
|
||||||
|
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x4C0
|
||||||
|
#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x4C4
|
||||||
|
#define QSERDES_RX_RX_IDAC_CAL_CONFIGURATION 0x4C8
|
||||||
|
#define QSERDES_RX_RX_IDAC_CAL_CONFIGURATION_2 0x4CC
|
||||||
|
#define QSERDES_RX_RX_IDAC_TSETTLE_LOW 0x4D0
|
||||||
|
#define QSERDES_RX_RX_IDAC_TSETTLE_HIGH 0x4D4
|
||||||
|
#define QSERDES_RX_RX_IDAC_ENDSAMP_LOW 0x4D8
|
||||||
|
#define QSERDES_RX_RX_IDAC_ENDSAMP_HIGH 0x4DC
|
||||||
|
#define QSERDES_RX_RX_IDAC_MIDPOINT_LOW 0x4E0
|
||||||
|
#define QSERDES_RX_RX_IDAC_MIDPOINT_HIGH 0x4E4
|
||||||
|
#define QSERDES_RX_RX_EQ_OFFSET_LSB 0x4E8
|
||||||
|
#define QSERDES_RX_RX_EQ_OFFSET_MSB 0x4EC
|
||||||
|
#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x4F0
|
||||||
|
#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x4F4
|
||||||
|
#define QSERDES_RX_SIGDET_ENABLES 0x4F8
|
||||||
|
#define QSERDES_RX_SIGDET_ENABLES_2 0x4FC
|
||||||
|
#define QSERDES_RX_SIGDET_CNTRL 0x500
|
||||||
|
#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x504
|
||||||
|
#define QSERDES_RX_SIGDET_TIMER_LIMIT 0x508
|
||||||
|
#define QSERDES_RX_RX_BAND 0x50C
|
||||||
|
#define QSERDES_RX_CDR_FREEZE_UP_DN 0x510
|
||||||
|
#define QSERDES_RX_RX_INTERFACE_MODE 0x514
|
||||||
|
#define QSERDES_RX_JITTER_GEN_MODE 0x518
|
||||||
|
#define QSERDES_RX_BUJ_AMP 0x51C
|
||||||
|
#define QSERDES_RX_SJ_AMP1 0x520
|
||||||
|
#define QSERDES_RX_SJ_AMP2 0x524
|
||||||
|
#define QSERDES_RX_SJ_PER1 0x528
|
||||||
|
#define QSERDES_RX_SJ_PER2 0x52C
|
||||||
|
#define QSERDES_RX_BUJ_STEP_FREQ1 0x530
|
||||||
|
#define QSERDES_RX_BUJ_STEP_FREQ2 0x534
|
||||||
|
#define QSERDES_RX_PPM_OFFSET1 0x538
|
||||||
|
#define QSERDES_RX_PPM_OFFSET2 0x53C
|
||||||
|
#define QSERDES_RX_SIGN_PPM_PERIOD1 0x540
|
||||||
|
#define QSERDES_RX_SIGN_PPM_PERIOD2 0x544
|
||||||
|
#define QSERDES_RX_SSC_CTRL 0x548
|
||||||
|
#define QSERDES_RX_SSC_COUNT1 0x54C
|
||||||
|
#define QSERDES_RX_SSC_COUNT2 0x550
|
||||||
|
#define QSERDES_RX_RX_ALOG_INTF_OBSV_CNTL 0x554
|
||||||
|
#define QSERDES_RX_PI_CTRL1 0x558
|
||||||
|
#define QSERDES_RX_PI_CTRL2 0x55C
|
||||||
|
#define QSERDES_RX_PI_QUAD 0x560
|
||||||
|
#define QSERDES_RX_IDATA1 0x564
|
||||||
|
#define QSERDES_RX_IDATA2 0x568
|
||||||
|
#define QSERDES_RX_AUX_DATA1 0x56C
|
||||||
|
#define QSERDES_RX_AUX_DATA2 0x570
|
||||||
|
#define QSERDES_RX_AC_JTAG_OUTP 0x574
|
||||||
|
#define QSERDES_RX_AC_JTAG_OUTN 0x578
|
||||||
|
#define QSERDES_RX_RX_SIGDET 0x57C
|
||||||
|
#define QSERDES_RX_RX_VDCOFF 0x580
|
||||||
|
#define QSERDES_RX_IDAC_CAL_ON 0x584
|
||||||
|
#define QSERDES_RX_IDAC_STATUS_I 0x588
|
||||||
|
#define QSERDES_RX_IDAC_STATUS_Q 0x58C
|
||||||
|
#define QSERDES_RX_IDAC_STATUS_A 0x590
|
||||||
|
#define QSERDES_RX_CALST_STATUS_I 0x594
|
||||||
|
#define QSERDES_RX_CALST_STATUS_Q 0x598
|
||||||
|
#define QSERDES_RX_CALST_STATUS_A 0x59C
|
||||||
|
#define QSERDES_RX_EOM_STATUS0 0x5A0
|
||||||
|
#define QSERDES_RX_EOM_STATUS1 0x5A4
|
||||||
|
#define QSERDES_RX_EOM_STATUS2 0x5A8
|
||||||
|
#define QSERDES_RX_EOM_STATUS3 0x5AC
|
||||||
|
#define QSERDES_RX_EOM_STATUS4 0x5B0
|
||||||
|
#define QSERDES_RX_EOM_STATUS5 0x5B4
|
||||||
|
#define QSERDES_RX_EOM_STATUS6 0x5B8
|
||||||
|
#define QSERDES_RX_EOM_STATUS7 0x5BC
|
||||||
|
#define QSERDES_RX_EOM_STATUS8 0x5C0
|
||||||
|
#define QSERDES_RX_EOM_STATUS9 0x5C4
|
||||||
|
#define QSERDES_RX_RX_ALOG_INTF_OBSV 0x5C8
|
||||||
|
#define QSERDES_RX_READ_EQCODE 0x5CC
|
||||||
|
#define QSERDES_RX_READ_OFFSETCODE 0x5D0
|
||||||
|
#define PCIE_PHY_SW_RESET 0x600
|
||||||
|
#define PCIE_PHY_POWER_DOWN_CONTROL 0x604
|
||||||
|
#define PCIE_PHY_START 0x608
|
||||||
|
#define PCIE_PHY_TXMGN_V1_V0 0x60C
|
||||||
|
#define PCIE_PHY_TXMGN_V3_V2 0x610
|
||||||
|
#define PCIE_PHY_TXMGN_LS_V4 0x614
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M6DB_V0 0x618
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M3P5DB_V0 0x61C
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M6DB_V1 0x620
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M3P5DB_V1 0x624
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M6DB_V2 0x628
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M3P5DB_V2 0x62C
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M6DB_V3 0x630
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M3P5DB_V3 0x634
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M6DB_V4 0x638
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M3P5DB_V4 0x63C
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M6DB_LS 0x640
|
||||||
|
#define PCIE_PHY_TXDEEMPH_M3P5DB_LS 0x644
|
||||||
|
#define PCIE_PHY_ENDPOINT_REFCLK_DRIVE 0x648
|
||||||
|
#define PCIE_PHY_RX_IDLE_DTCT_CNTRL 0x64C
|
||||||
|
#define PCIE_PHY_POWER_STATE_CONFIG1 0x650
|
||||||
|
#define PCIE_PHY_POWER_STATE_CONFIG2 0x654
|
||||||
|
#define PCIE_PHY_POWER_STATE_CONFIG3 0x658
|
||||||
|
#define PCIE_PHY_RCVR_DTCT_DLY_P1U2_L 0x65C
|
||||||
|
#define PCIE_PHY_RCVR_DTCT_DLY_P1U2_H 0x660
|
||||||
|
#define PCIE_PHY_RCVR_DTCT_DLY_U3_L 0x664
|
||||||
|
#define PCIE_PHY_RCVR_DTCT_DLY_U3_H 0x668
|
||||||
|
#define PCIE_PHY_LOCK_DETECT_CONFIG1 0x66C
|
||||||
|
#define PCIE_PHY_LOCK_DETECT_CONFIG2 0x670
|
||||||
|
#define PCIE_PHY_LOCK_DETECT_CONFIG3 0x674
|
||||||
|
#define PCIE_PHY_TSYNC_RSYNC_TIME 0x678
|
||||||
|
#define PCIE_PHY_SIGDET_LOW_2_IDLE_TIME 0x67C
|
||||||
|
#define PCIE_PHY_BEACON_2_IDLE_TIME_L 0x680
|
||||||
|
#define PCIE_PHY_BEACON_2_IDLE_TIME_H 0x684
|
||||||
|
#define PCIE_PHY_PWRUP_RESET_DLY_TIME_SYSCLK 0x688
|
||||||
|
#define PCIE_PHY_PWRUP_RESET_DLY_TIME_AUXCLK 0x68C
|
||||||
|
#define PCIE_PHY_LFPS_DET_HIGH_COUNT_VAL 0x690
|
||||||
|
#define PCIE_PHY_LFPS_TX_ECSTART_EQTLOCK 0x694
|
||||||
|
#define PCIE_PHY_LFPS_TX_END_CNT_P2U3_START 0x698
|
||||||
|
#define PCIE_PHY_RXEQTRAINING_WAIT_TIME 0x69C
|
||||||
|
#define PCIE_PHY_RXEQTRAINING_RUN_TIME 0x6A0
|
||||||
|
#define PCIE_PHY_TXONESZEROS_RUN_LENGTH 0x6A4
|
||||||
|
#define PCIE_PHY_FLL_CNTRL1 0x6A8
|
||||||
|
#define PCIE_PHY_FLL_CNTRL2 0x6AC
|
||||||
|
#define PCIE_PHY_FLL_CNT_VAL_L 0x6B0
|
||||||
|
#define PCIE_PHY_FLL_CNT_VAL_H_TOL 0x6B4
|
||||||
|
#define PCIE_PHY_FLL_MAN_CODE 0x6B8
|
||||||
|
#define PCIE_PHY_AUTONOMOUS_MODE_CTRL 0x6BC
|
||||||
|
#define PCIE_PHY_LFPS_RXTERM_IRQ_CLEAR 0x6C0
|
||||||
|
#define PCIE_PHY_ARCVR_DTCT_EN_PERIOD 0x6C4
|
||||||
|
#define PCIE_PHY_ARCVR_DTCT_CM_DLY 0x6C8
|
||||||
|
#define PCIE_PHY_ALFPS_DEGLITCH_VAL 0x6CC
|
||||||
|
#define PCIE_PHY_INSIG_SW_CTRL1 0x6D0
|
||||||
|
#define PCIE_PHY_INSIG_SW_CTRL2 0x6D4
|
||||||
|
#define PCIE_PHY_INSIG_SW_CTRL3 0x6D8
|
||||||
|
#define PCIE_PHY_INSIG_MX_CTRL1 0x6DC
|
||||||
|
#define PCIE_PHY_INSIG_MX_CTRL2 0x6E0
|
||||||
|
#define PCIE_PHY_INSIG_MX_CTRL3 0x6E4
|
||||||
|
#define PCIE_PHY_TEST_CONTROL 0x6E8
|
||||||
|
#define PCIE_PHY_BIST_CTRL 0x6EC
|
||||||
|
#define PCIE_PHY_PRBS_POLY0 0x6F0
|
||||||
|
#define PCIE_PHY_PRBS_POLY1 0x6F4
|
||||||
|
#define PCIE_PHY_PRBS_SEED0 0x6F8
|
||||||
|
#define PCIE_PHY_PRBS_SEED1 0x6FC
|
||||||
|
#define PCIE_PHY_FIXED_PAT_CTRL 0x700
|
||||||
|
#define PCIE_PHY_FIXED_PAT0 0x704
|
||||||
|
#define PCIE_PHY_FIXED_PAT1 0x708
|
||||||
|
#define PCIE_PHY_FIXED_PAT2 0x70C
|
||||||
|
#define PCIE_PHY_FIXED_PAT3 0x710
|
||||||
|
#define PCIE_PHY_SPARE1 0x714
|
||||||
|
#define PCIE_PHY_BIST_CHK_ERR_CNT_L 0x718
|
||||||
|
#define PCIE_PHY_BIST_CHK_ERR_CNT_H 0x71C
|
||||||
|
#define PCIE_PHY_BIST_CHK_STATUS 0x720
|
||||||
|
#define PCIE_PHY_LFPS_RXTERM_IRQ_SOURCE 0x724
|
||||||
|
#define PCIE_PHY_PCS_STATUS 0x728
|
||||||
|
#define PCIE_PHY_PCS_STATUS2 0x72C
|
||||||
|
#define PCIE_PHY_REVISION_ID0 0x730
|
||||||
|
#define PCIE_PHY_REVISION_ID1 0x734
|
||||||
|
#define PCIE_PHY_REVISION_ID2 0x738
|
||||||
|
#define PCIE_PHY_REVISION_ID3 0x73C
|
||||||
|
#define PCIE_PHY_DEBUG_BUS_0_STATUS 0x740
|
||||||
|
#define PCIE_PHY_DEBUG_BUS_1_STATUS 0x744
|
||||||
|
#define PCIE_PHY_DEBUG_BUS_2_STATUS 0x748
|
||||||
|
#define PCIE_PHY_DEBUG_BUS_3_STATUS 0x74C
|
||||||
|
#endif
|
254
include/linux/msm_ep_pcie.h
Normal file
254
include/linux/msm_ep_pcie.h
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
/* Copyright (c) 2015, 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,
|
||||||
|
};
|
||||||
|
|
||||||
|
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_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_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)(void);
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
#endif
|
Loading…
Add table
Reference in a new issue