Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: mediatek-gen3: Add Airoha EN7581 support

Introduce support for Airoha EN7581 PCIe controller to mediatek-gen3
PCIe controller driver.

Link: https://lore.kernel.org/linux-pci/aca00bd672ee576ad96d279414fc0835ff31f637.1720022580.git.lorenzo@kernel.org
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Tested-by: Zhengping Zhang <zhengping.zhang@airoha.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Acked-by: Jianjun Wang <jianjun.wang@mediatek.com>

authored by

Lorenzo Bianconi and committed by
Krzysztof Wilczyński
f6ab8983 ee9eabbe

+113 -2
+1 -1
drivers/pci/controller/Kconfig
··· 196 196 197 197 config PCIE_MEDIATEK_GEN3 198 198 tristate "MediaTek Gen3 PCIe controller" 199 - depends on ARCH_MEDIATEK || COMPILE_TEST 199 + depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST 200 200 depends on PCI_MSI 201 201 help 202 202 Adds support for PCIe Gen3 MAC controller for MediaTek SoCs.
+112 -1
drivers/pci/controller/pcie-mediatek-gen3.c
··· 6 6 * Author: Jianjun Wang <jianjun.wang@mediatek.com> 7 7 */ 8 8 9 + #include <linux/bitfield.h> 9 10 #include <linux/clk.h> 11 + #include <linux/clk-provider.h> 10 12 #include <linux/delay.h> 11 13 #include <linux/iopoll.h> 12 14 #include <linux/irq.h> ··· 17 15 #include <linux/kernel.h> 18 16 #include <linux/module.h> 19 17 #include <linux/msi.h> 18 + #include <linux/of_device.h> 19 + #include <linux/of_pci.h> 20 20 #include <linux/pci.h> 21 21 #include <linux/phy/phy.h> 22 22 #include <linux/platform_device.h> ··· 32 28 #define PCIE_PCI_IDS_1 0x9c 33 29 #define PCI_CLASS(class) (class << 8) 34 30 #define PCIE_RC_MODE BIT(0) 31 + 32 + #define PCIE_EQ_PRESET_01_REG 0x100 33 + #define PCIE_VAL_LN0_DOWNSTREAM GENMASK(6, 0) 34 + #define PCIE_VAL_LN0_UPSTREAM GENMASK(14, 8) 35 + #define PCIE_VAL_LN1_DOWNSTREAM GENMASK(22, 16) 36 + #define PCIE_VAL_LN1_UPSTREAM GENMASK(30, 24) 35 37 36 38 #define PCIE_CFGNUM_REG 0x140 37 39 #define PCIE_CFG_DEVFN(devfn) ((devfn) & GENMASK(7, 0)) ··· 78 68 #define PCIE_MSI_SET_ENABLE_REG 0x190 79 69 #define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0) 80 70 71 + #define PCIE_PIPE4_PIE8_REG 0x338 72 + #define PCIE_K_FINETUNE_MAX GENMASK(5, 0) 73 + #define PCIE_K_FINETUNE_ERR GENMASK(7, 6) 74 + #define PCIE_K_PRESET_TO_USE GENMASK(18, 8) 75 + #define PCIE_K_PHYPARAM_QUERY BIT(19) 76 + #define PCIE_K_QUERY_TIMEOUT BIT(20) 77 + #define PCIE_K_PRESET_TO_USE_16G GENMASK(31, 21) 78 + 81 79 #define PCIE_MSI_SET_BASE_REG 0xc00 82 80 #define PCIE_MSI_SET_OFFSET 0x10 83 81 #define PCIE_MSI_SET_STATUS_OFFSET 0x04 ··· 118 100 #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) 119 101 #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) 120 102 121 - #define MAX_NUM_PHY_RESETS 1 103 + #define MAX_NUM_PHY_RESETS 3 104 + 105 + /* Time in ms needed to complete PCIe reset on EN7581 SoC */ 106 + #define PCIE_EN7581_RESET_TIME_MS 100 122 107 123 108 struct mtk_gen3_pcie; 124 109 ··· 868 847 return 0; 869 848 } 870 849 850 + static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie) 851 + { 852 + struct device *dev = pcie->dev; 853 + int err; 854 + u32 val; 855 + 856 + /* 857 + * Wait for the time needed to complete the bulk assert in 858 + * mtk_pcie_setup for EN7581 SoC. 859 + */ 860 + mdelay(PCIE_EN7581_RESET_TIME_MS); 861 + 862 + err = phy_init(pcie->phy); 863 + if (err) { 864 + dev_err(dev, "failed to initialize PHY\n"); 865 + return err; 866 + } 867 + 868 + err = phy_power_on(pcie->phy); 869 + if (err) { 870 + dev_err(dev, "failed to power on PHY\n"); 871 + goto err_phy_on; 872 + } 873 + 874 + err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); 875 + if (err) { 876 + dev_err(dev, "failed to deassert PHYs\n"); 877 + goto err_phy_deassert; 878 + } 879 + 880 + /* 881 + * Wait for the time needed to complete the bulk de-assert above. 882 + * This time is specific for EN7581 SoC. 883 + */ 884 + mdelay(PCIE_EN7581_RESET_TIME_MS); 885 + 886 + pm_runtime_enable(dev); 887 + pm_runtime_get_sync(dev); 888 + 889 + err = clk_bulk_prepare(pcie->num_clks, pcie->clks); 890 + if (err) { 891 + dev_err(dev, "failed to prepare clock\n"); 892 + goto err_clk_prepare; 893 + } 894 + 895 + val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | 896 + FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | 897 + FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | 898 + FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); 899 + writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); 900 + 901 + val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | 902 + FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | 903 + FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | 904 + FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); 905 + writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); 906 + 907 + err = clk_bulk_enable(pcie->num_clks, pcie->clks); 908 + if (err) { 909 + dev_err(dev, "failed to prepare clock\n"); 910 + goto err_clk_enable; 911 + } 912 + 913 + return 0; 914 + 915 + err_clk_enable: 916 + clk_bulk_unprepare(pcie->num_clks, pcie->clks); 917 + err_clk_prepare: 918 + pm_runtime_put_sync(dev); 919 + pm_runtime_disable(dev); 920 + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); 921 + err_phy_deassert: 922 + phy_power_off(pcie->phy); 923 + err_phy_on: 924 + phy_exit(pcie->phy); 925 + 926 + return err; 927 + } 928 + 871 929 static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie) 872 930 { 873 931 struct device *dev = pcie->dev; ··· 1213 1113 }, 1214 1114 }; 1215 1115 1116 + static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = { 1117 + .power_up = mtk_pcie_en7581_power_up, 1118 + .phy_resets = { 1119 + .id[0] = "phy-lane0", 1120 + .id[1] = "phy-lane1", 1121 + .id[2] = "phy-lane2", 1122 + .num_resets = 3, 1123 + }, 1124 + }; 1125 + 1216 1126 static const struct of_device_id mtk_pcie_of_match[] = { 1127 + { .compatible = "airoha,en7581-pcie", .data = &mtk_pcie_soc_en7581 }, 1217 1128 { .compatible = "mediatek,mt8192-pcie", .data = &mtk_pcie_soc_mt8192 }, 1218 1129 {}, 1219 1130 };