Source
x
// SPDX-License-Identifier: GPL-2.0+ OR X11
/*
* Copyright 2018-2019 NXP
*
* PCIe Gen4 driver for NXP Layerscape SoCs
* Author: Hou Zhiqiang <Minder.Hou@gmail.com>
*/
DECLARE_GLOBAL_DATA_PTR;
LIST_HEAD(ls_pcie_g4_list);
static u64 bar_size[4] = {
PCIE_BAR0_SIZE,
PCIE_BAR1_SIZE,
PCIE_BAR2_SIZE,
PCIE_BAR4_SIZE
};
static int ls_pcie_g4_ltssm(struct ls_pcie_g4 *pcie)
{
u32 state;
state = pf_ctrl_readl(pcie, PCIE_LTSSM_STA) & LTSSM_STATE_MASK;
return state;
}
static int ls_pcie_g4_link_up(struct ls_pcie_g4 *pcie)
{
int ltssm;
ltssm = ls_pcie_g4_ltssm(pcie);
if (ltssm != LTSSM_PCIE_L0)
return 0;
return 1;
}
static void ls_pcie_g4_ep_enable_cfg(struct ls_pcie_g4 *pcie)
{
ccsr_writel(pcie, GPEX_CFG_READY, PCIE_CONFIG_READY);
}
static void ls_pcie_g4_cfg_set_target(struct ls_pcie_g4 *pcie, u32 target)
{
ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(0), target);
ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
}
static int ls_pcie_g4_outbound_win_set(struct ls_pcie_g4 *pcie, int idx,
int type, u64 phys, u64 bus_addr,
pci_size_t size)
{
u32 val;
u32 size_h, size_l;
if (idx >= PAB_WINS_NUM)
return -EINVAL;
size_h = upper_32_bits(~(size - 1));
size_l = lower_32_bits(~(size - 1));
val = ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
(AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
AXI_AMAP_CTRL_EN);
val |= ((type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
((size_l >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
ccsr_writel(pcie, PAB_AXI_AMAP_CTRL(idx), val);
ccsr_writel(pcie, PAB_AXI_AMAP_AXI_WIN(idx), lower_32_bits(phys));
ccsr_writel(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(idx), upper_32_bits(phys));
ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
ccsr_writel(pcie, PAB_EXT_AXI_AMAP_SIZE(idx), size_h);
return 0;
}