Skip to content

Commit ade7da1

Browse files
AngeloGioacchino Del Regnokwilczynski
authored andcommitted
PCI: mediatek-gen3: Add support for setting max-link-speed limit
Add support for respecting the max-link-speed devicetree property, forcing a maximum speed (Gen) for a PCI-Express port. Since the MediaTek PCIe Gen3 controllers also expose the maximum supported link speed in the PCIE_BASE_CFG register, if property max-link-speed is specified in devicetree, validate it against the controller capabilities and proceed setting the limitations only if the wanted Gen is lower than the maximum one that is supported by the controller itself (otherwise it makes no sense!). Link: https://lore.kernel.org/r/20241104114935.172908-2-angelogioacchino.delregno@collabora.com Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> [kwilczynski: change dev_dbg() to dev_info() and update message wording] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Reviewed-by: Fei Shao <fshao@chromium.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
1 parent 9852d85 commit ade7da1

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

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

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828

2929
#include "../pci.h"
3030

31+
#define PCIE_BASE_CFG_REG 0x14
32+
#define PCIE_BASE_CFG_SPEED GENMASK(15, 8)
33+
3134
#define PCIE_SETTING_REG 0x80
35+
#define PCIE_SETTING_GEN_SUPPORT GENMASK(14, 12)
3236
#define PCIE_PCI_IDS_1 0x9c
3337
#define PCI_CLASS(class) (class << 8)
3438
#define PCIE_RC_MODE BIT(0)
@@ -125,6 +129,9 @@
125129

126130
struct mtk_gen3_pcie;
127131

132+
#define PCIE_CONF_LINK2_CTL_STS (PCIE_CFG_OFFSET_ADDR + 0xb0)
133+
#define PCIE_CONF_LINK2_LCR2_LINK_SPEED GENMASK(3, 0)
134+
128135
/**
129136
* struct mtk_gen3_pcie_pdata - differentiate between host generations
130137
* @power_up: pcie power_up callback
@@ -160,6 +167,7 @@ struct mtk_msi_set {
160167
* @phy: PHY controller block
161168
* @clks: PCIe clocks
162169
* @num_clks: PCIe clocks count for this port
170+
* @max_link_speed: Maximum link speed (PCIe Gen) for this port
163171
* @irq: PCIe controller interrupt number
164172
* @saved_irq_state: IRQ enable state saved at suspend time
165173
* @irq_lock: lock protecting IRQ register access
@@ -180,6 +188,7 @@ struct mtk_gen3_pcie {
180188
struct phy *phy;
181189
struct clk_bulk_data *clks;
182190
int num_clks;
191+
u8 max_link_speed;
183192

184193
int irq;
185194
u32 saved_irq_state;
@@ -381,11 +390,27 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
381390
int err;
382391
u32 val;
383392

384-
/* Set as RC mode */
393+
/* Set as RC mode and set controller PCIe Gen speed restriction, if any */
385394
val = readl_relaxed(pcie->base + PCIE_SETTING_REG);
386395
val |= PCIE_RC_MODE;
396+
if (pcie->max_link_speed) {
397+
val &= ~PCIE_SETTING_GEN_SUPPORT;
398+
399+
/* Can enable link speed support only from Gen2 onwards */
400+
if (pcie->max_link_speed >= 2)
401+
val |= FIELD_PREP(PCIE_SETTING_GEN_SUPPORT,
402+
GENMASK(pcie->max_link_speed - 2, 0));
403+
}
387404
writel_relaxed(val, pcie->base + PCIE_SETTING_REG);
388405

406+
/* Set Link Control 2 (LNKCTL2) speed restriction, if any */
407+
if (pcie->max_link_speed) {
408+
val = readl_relaxed(pcie->base + PCIE_CONF_LINK2_CTL_STS);
409+
val &= ~PCIE_CONF_LINK2_LCR2_LINK_SPEED;
410+
val |= FIELD_PREP(PCIE_CONF_LINK2_LCR2_LINK_SPEED, pcie->max_link_speed);
411+
writel_relaxed(val, pcie->base + PCIE_CONF_LINK2_CTL_STS);
412+
}
413+
389414
/* Set class code */
390415
val = readl_relaxed(pcie->base + PCIE_PCI_IDS_1);
391416
val &= ~GENMASK(31, 8);
@@ -1004,9 +1029,21 @@ static void mtk_pcie_power_down(struct mtk_gen3_pcie *pcie)
10041029
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
10051030
}
10061031

1032+
static int mtk_pcie_get_controller_max_link_speed(struct mtk_gen3_pcie *pcie)
1033+
{
1034+
u32 val;
1035+
int ret;
1036+
1037+
val = readl_relaxed(pcie->base + PCIE_BASE_CFG_REG);
1038+
val = FIELD_GET(PCIE_BASE_CFG_SPEED, val);
1039+
ret = fls(val);
1040+
1041+
return ret > 0 ? ret : -EINVAL;
1042+
}
1043+
10071044
static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)
10081045
{
1009-
int err;
1046+
int err, max_speed;
10101047

10111048
err = mtk_pcie_parse_port(pcie);
10121049
if (err)
@@ -1031,6 +1068,20 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)
10311068
if (err)
10321069
return err;
10331070

1071+
err = of_pci_get_max_link_speed(pcie->dev->of_node);
1072+
if (err) {
1073+
/* Get the maximum speed supported by the controller */
1074+
max_speed = mtk_pcie_get_controller_max_link_speed(pcie);
1075+
1076+
/* Set max_link_speed only if the controller supports it */
1077+
if (max_speed >= 0 && max_speed <= err) {
1078+
pcie->max_link_speed = err;
1079+
dev_info(pcie->dev,
1080+
"maximum controller link speed Gen%d, overriding to Gen%u",
1081+
max_speed, pcie->max_link_speed);
1082+
}
1083+
}
1084+
10341085
/* Try link up */
10351086
err = mtk_pcie_startup_port(pcie);
10361087
if (err)

0 commit comments

Comments
 (0)