Skip to content

Commit f6ab898

Browse files
LorenzoBianconikwilczynski
authored andcommitted
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 <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]> Tested-by: Zhengping Zhang <[email protected]> Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Acked-by: Jianjun Wang <[email protected]>
1 parent ee9eabb commit f6ab898

File tree

2 files changed

+113
-2
lines changed

2 files changed

+113
-2
lines changed

drivers/pci/controller/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ config PCIE_MEDIATEK
196196

197197
config PCIE_MEDIATEK_GEN3
198198
tristate "MediaTek Gen3 PCIe controller"
199-
depends on ARCH_MEDIATEK || COMPILE_TEST
199+
depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST
200200
depends on PCI_MSI
201201
help
202202
Adds support for PCIe Gen3 MAC controller for MediaTek SoCs.

drivers/pci/controller/pcie-mediatek-gen3.c

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
* Author: Jianjun Wang <[email protected]>
77
*/
88

9+
#include <linux/bitfield.h>
910
#include <linux/clk.h>
11+
#include <linux/clk-provider.h>
1012
#include <linux/delay.h>
1113
#include <linux/iopoll.h>
1214
#include <linux/irq.h>
@@ -15,6 +17,8 @@
1517
#include <linux/kernel.h>
1618
#include <linux/module.h>
1719
#include <linux/msi.h>
20+
#include <linux/of_device.h>
21+
#include <linux/of_pci.h>
1822
#include <linux/pci.h>
1923
#include <linux/phy/phy.h>
2024
#include <linux/platform_device.h>
@@ -29,6 +33,12 @@
2933
#define PCI_CLASS(class) (class << 8)
3034
#define PCIE_RC_MODE BIT(0)
3135

36+
#define PCIE_EQ_PRESET_01_REG 0x100
37+
#define PCIE_VAL_LN0_DOWNSTREAM GENMASK(6, 0)
38+
#define PCIE_VAL_LN0_UPSTREAM GENMASK(14, 8)
39+
#define PCIE_VAL_LN1_DOWNSTREAM GENMASK(22, 16)
40+
#define PCIE_VAL_LN1_UPSTREAM GENMASK(30, 24)
41+
3242
#define PCIE_CFGNUM_REG 0x140
3343
#define PCIE_CFG_DEVFN(devfn) ((devfn) & GENMASK(7, 0))
3444
#define PCIE_CFG_BUS(bus) (((bus) << 8) & GENMASK(15, 8))
@@ -68,6 +78,14 @@
6878
#define PCIE_MSI_SET_ENABLE_REG 0x190
6979
#define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0)
7080

81+
#define PCIE_PIPE4_PIE8_REG 0x338
82+
#define PCIE_K_FINETUNE_MAX GENMASK(5, 0)
83+
#define PCIE_K_FINETUNE_ERR GENMASK(7, 6)
84+
#define PCIE_K_PRESET_TO_USE GENMASK(18, 8)
85+
#define PCIE_K_PHYPARAM_QUERY BIT(19)
86+
#define PCIE_K_QUERY_TIMEOUT BIT(20)
87+
#define PCIE_K_PRESET_TO_USE_16G GENMASK(31, 21)
88+
7189
#define PCIE_MSI_SET_BASE_REG 0xc00
7290
#define PCIE_MSI_SET_OFFSET 0x10
7391
#define PCIE_MSI_SET_STATUS_OFFSET 0x04
@@ -100,7 +118,10 @@
100118
#define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0)
101119
#define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2)
102120

103-
#define MAX_NUM_PHY_RESETS 1
121+
#define MAX_NUM_PHY_RESETS 3
122+
123+
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
124+
#define PCIE_EN7581_RESET_TIME_MS 100
104125

105126
struct mtk_gen3_pcie;
106127

@@ -847,6 +868,85 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
847868
return 0;
848869
}
849870

871+
static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
872+
{
873+
struct device *dev = pcie->dev;
874+
int err;
875+
u32 val;
876+
877+
/*
878+
* Wait for the time needed to complete the bulk assert in
879+
* mtk_pcie_setup for EN7581 SoC.
880+
*/
881+
mdelay(PCIE_EN7581_RESET_TIME_MS);
882+
883+
err = phy_init(pcie->phy);
884+
if (err) {
885+
dev_err(dev, "failed to initialize PHY\n");
886+
return err;
887+
}
888+
889+
err = phy_power_on(pcie->phy);
890+
if (err) {
891+
dev_err(dev, "failed to power on PHY\n");
892+
goto err_phy_on;
893+
}
894+
895+
err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
896+
if (err) {
897+
dev_err(dev, "failed to deassert PHYs\n");
898+
goto err_phy_deassert;
899+
}
900+
901+
/*
902+
* Wait for the time needed to complete the bulk de-assert above.
903+
* This time is specific for EN7581 SoC.
904+
*/
905+
mdelay(PCIE_EN7581_RESET_TIME_MS);
906+
907+
pm_runtime_enable(dev);
908+
pm_runtime_get_sync(dev);
909+
910+
err = clk_bulk_prepare(pcie->num_clks, pcie->clks);
911+
if (err) {
912+
dev_err(dev, "failed to prepare clock\n");
913+
goto err_clk_prepare;
914+
}
915+
916+
val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
917+
FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
918+
FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
919+
FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
920+
writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG);
921+
922+
val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
923+
FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
924+
FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
925+
FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
926+
writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
927+
928+
err = clk_bulk_enable(pcie->num_clks, pcie->clks);
929+
if (err) {
930+
dev_err(dev, "failed to prepare clock\n");
931+
goto err_clk_enable;
932+
}
933+
934+
return 0;
935+
936+
err_clk_enable:
937+
clk_bulk_unprepare(pcie->num_clks, pcie->clks);
938+
err_clk_prepare:
939+
pm_runtime_put_sync(dev);
940+
pm_runtime_disable(dev);
941+
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
942+
err_phy_deassert:
943+
phy_power_off(pcie->phy);
944+
err_phy_on:
945+
phy_exit(pcie->phy);
946+
947+
return err;
948+
}
949+
850950
static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie)
851951
{
852952
struct device *dev = pcie->dev;
@@ -1113,7 +1213,18 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8192 = {
11131213
},
11141214
};
11151215

1216+
static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = {
1217+
.power_up = mtk_pcie_en7581_power_up,
1218+
.phy_resets = {
1219+
.id[0] = "phy-lane0",
1220+
.id[1] = "phy-lane1",
1221+
.id[2] = "phy-lane2",
1222+
.num_resets = 3,
1223+
},
1224+
};
1225+
11161226
static const struct of_device_id mtk_pcie_of_match[] = {
1227+
{ .compatible = "airoha,en7581-pcie", .data = &mtk_pcie_soc_en7581 },
11171228
{ .compatible = "mediatek,mt8192-pcie", .data = &mtk_pcie_soc_mt8192 },
11181229
{},
11191230
};

0 commit comments

Comments
 (0)