diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 760171b70bd4..f44003c6cabb 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -192,6 +192,7 @@ struct rk_pcie { u32 msi_vector_num; struct workqueue_struct *hot_rst_wq; struct work_struct hot_rst_work; + u32 comp_prst[2]; }; struct rk_pcie_of_data { @@ -2081,11 +2082,25 @@ retry_regulator: rk_pcie->is_signal_test = true; } - /* Force into compliance mode */ - if (device_property_read_bool(dev, "rockchip,compliance-mode")) { - val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); - val |= BIT(4); - dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); + /* + * Force into compliance mode + * comp_prst is a two dimensional array of which the first element + * stands for speed mode, and the second one is preset value encoding: + * [0] 0->SMA tool control the signal switch, 1/2/3 is for manual Gen setting + * [1] transmitter setting for manual Gen setting, valid only if [0] isn't zero. + */ + if (device_property_read_u32_array(dev, "rockchip,compliance-mode", + rk_pcie->comp_prst, 2)) { + BUG_ON(rk_pcie->comp_prst[0] > 3 || rk_pcie->comp_prst[1] > 10); + if (!rk_pcie->comp_prst[0]) { + dev_info(dev, "Auto compliance mode for SMA tool.\n"); + } else { + dev_info(dev, "compliance mode for soldered board Gen%d, P%d.\n", + rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]); + val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); + val |= BIT(4) | rk_pcie->comp_prst[0] | (rk_pcie->comp_prst[1] << 12); + dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); + } rk_pcie->is_signal_test = true; }