FILE
pcie-cadence-hpa.c
File preview with syntax highlighting.
linux-6.19.14/drivers/pci/controller/cadence/pcie-cadence-hpa.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Cadence PCIe controller driver. 4 * 5 * Copyright (c) 2024, Cadence Design Systems 6 * Author: Manikandan K Pillai <mpillai@cadence.com> 7 */ 8#include <linux/kernel.h> 9#include <linux/of.h> 10 11#include "pcie-cadence.h" 12 13bool cdns_pcie_hpa_link_up(struct cdns_pcie *pcie) 14{ 15 u32 pl_reg_val; 16 17 pl_reg_val = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, CDNS_PCIE_HPA_PHY_DBG_STS_REG0); 18 if (pl_reg_val & GENMASK(0, 0)) 19 return true; 20 return false; 21} 22EXPORT_SYMBOL_GPL(cdns_pcie_hpa_link_up); 23 24void cdns_pcie_hpa_detect_quiet_min_delay_set(struct cdns_pcie *pcie) 25{ 26 u32 delay = 0x3; 27 u32 ltssm_control_cap; 28 29 /* Set the LTSSM Detect Quiet state min. delay to 2ms */ 30 ltssm_control_cap = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, 31 CDNS_PCIE_HPA_PHY_LAYER_CFG0); 32 ltssm_control_cap = ((ltssm_control_cap & 33 ~CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY_MASK) | 34 CDNS_PCIE_HPA_DETECT_QUIET_MIN_DELAY(delay)); 35 36 cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, 37 CDNS_PCIE_HPA_PHY_LAYER_CFG0, ltssm_control_cap); 38} 39EXPORT_SYMBOL_GPL(cdns_pcie_hpa_detect_quiet_min_delay_set); 40 41void cdns_pcie_hpa_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn, 42 u32 r, bool is_io, 43 u64 cpu_addr, u64 pci_addr, size_t size) 44{ 45 /* 46 * roundup_pow_of_two() returns an unsigned long, which is not suited 47 * for 64bit values 48 */ 49 u64 sz = 1ULL << fls64(size - 1); 50 int nbits = ilog2(sz); 51 u32 addr0, addr1, desc0, desc1, ctrl0; 52 53 if (nbits < 8) 54 nbits = 8; 55 56 /* Set the PCI address */ 57 addr0 = CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) | 58 (lower_32_bits(pci_addr) & GENMASK(31, 8)); 59 addr1 = upper_32_bits(pci_addr); 60 61 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 62 CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(r), addr0); 63 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 64 CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(r), addr1); 65 66 /* Set the PCIe header descriptor */ 67 if (is_io) 68 desc0 = CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_IO; 69 else 70 desc0 = CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_MEM; 71 desc1 = 0; 72 ctrl0 = 0; 73 74 /* 75 * Whether Bit [26] is set or not inside DESC0 register of the outbound 76 * PCIe descriptor, the PCI function number must be set into 77 * Bits [31:24] of DESC1 anyway. 78 * 79 * In Root Complex mode, the function number is always 0 but in Endpoint 80 * mode, the PCIe controller may support more than one function. This 81 * function number needs to be set properly into the outbound PCIe 82 * descriptor. 83 * 84 * Besides, setting Bit [26] is mandatory when in Root Complex mode: 85 * then the driver must provide the bus, resp. device, number in 86 * Bits [31:24] of DESC1, resp. Bits[23:16] of DESC0. Like the function 87 * number, the device number is always 0 in Root Complex mode. 88 * 89 * However when in Endpoint mode, we can clear Bit [26] of DESC0, hence 90 * the PCIe controller will use the captured values for the bus and 91 * device numbers. 92 */ 93 if (pcie->is_rc) { 94 /* The device and function numbers are always 0 */ 95 desc1 = CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS(busnr) | 96 CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(0); 97 ctrl0 = CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_BUS | 98 CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN; 99 } else { 100 /* 101 * Use captured values for bus and device numbers but still 102 * need to set the function number 103 */ 104 desc1 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(fn); 105 } 106 107 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 108 CDNS_PCIE_HPA_AT_OB_REGION_DESC0(r), desc0); 109 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 110 CDNS_PCIE_HPA_AT_OB_REGION_DESC1(r), desc1); 111 112 addr0 = CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) | 113 (lower_32_bits(cpu_addr) & GENMASK(31, 8)); 114 addr1 = upper_32_bits(cpu_addr); 115 116 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 117 CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(r), addr0); 118 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 119 CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(r), addr1); 120 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 121 CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(r), ctrl0); 122} 123EXPORT_SYMBOL_GPL(cdns_pcie_hpa_set_outbound_region); 124 125void cdns_pcie_hpa_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, 126 u8 busnr, u8 fn, 127 u32 r, u64 cpu_addr) 128{ 129 u32 addr0, addr1, desc0, desc1, ctrl0; 130 131 desc0 = CDNS_PCIE_HPA_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG; 132 desc1 = 0; 133 ctrl0 = 0; 134 135 /* See cdns_pcie_set_outbound_region() comments above */ 136 if (pcie->is_rc) { 137 desc1 = CDNS_PCIE_HPA_AT_OB_REGION_DESC1_BUS(busnr) | 138 CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(0); 139 ctrl0 = CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_BUS | 140 CDNS_PCIE_HPA_AT_OB_REGION_CTRL0_SUPPLY_DEV_FN; 141 } else { 142 desc1 |= CDNS_PCIE_HPA_AT_OB_REGION_DESC1_DEVFN(fn); 143 } 144 145 addr0 = CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0_NBITS(17) | 146 (lower_32_bits(cpu_addr) & GENMASK(31, 8)); 147 addr1 = upper_32_bits(cpu_addr); 148 149 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 150 CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(r), 0); 151 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 152 CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(r), 0); 153 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 154 CDNS_PCIE_HPA_AT_OB_REGION_DESC0(r), desc0); 155 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 156 CDNS_PCIE_HPA_AT_OB_REGION_DESC1(r), desc1); 157 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 158 CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(r), addr0); 159 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 160 CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(r), addr1); 161 cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, 162 CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(r), ctrl0); 163} 164EXPORT_SYMBOL_GPL(cdns_pcie_hpa_set_outbound_region_for_normal_msg); 165 166MODULE_LICENSE("GPL"); 167MODULE_DESCRIPTION("Cadence PCIe controller driver");
~/
Read-only file preview.