[][Add PCIe max link width adjustment feature]

[Description]
Add PCIe max link width adjustment feature.

[Release-log]
N/A

Change-Id: If4a7f53c8be8c6cf18b8febffd9fbfe88c743ff9
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7422117
diff --git a/target/linux/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c b/target/linux/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c
index 0e01fde..4012dba 100644
--- a/target/linux/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/target/linux/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -142,6 +142,7 @@
 	int num_clks;
 
 	int irq;
+	int max_link_width;
 	int direct_msi_enable;
 	int direct_msi[PCIE_MSI_IRQS_PER_SET];
 	u32 saved_irq_state;
@@ -211,6 +212,26 @@
 	.write = mtk_pcie_config_write,
 };
 
+/**
+ * This function will try to find the limitation of link width by finding
+ * a property called "max-link-width" of the given device node.
+ *
+ * @node: device tree node with the max link width information
+ *
+ * Returns the associated max link width from DT, or a negative value if the
+ * required property is not found or is invalid.
+ */
+int of_pci_get_max_link_width(struct device_node *node)
+{
+	u32 max_link_width = 0;
+
+	if (of_property_read_u32(node, "max-link-width", &max_link_width) ||
+	    max_link_width == 0 || max_link_width > 2)
+		return -EINVAL;
+
+	return max_link_width;
+}
+
 static int mtk_pcie_set_trans_table(struct mtk_pcie_port *port,
 				    resource_size_t cpu_addr,
 				    resource_size_t pci_addr,
@@ -292,6 +313,16 @@
 	val |= PCIE_RC_MODE;
 	writel_relaxed(val, port->base + PCIE_SETTING_REG);
 
+	/* Set link width*/
+	val = readl_relaxed(port->base + PCIE_SETTING_REG);
+	if (port->max_link_width == 1) {
+		val &= ~GENMASK(11, 8);
+	} else if (port->max_link_width == 2) {
+		val &= ~GENMASK(11, 8);
+		val |= BIT(8);
+	}
+	writel_relaxed(val, port->base + PCIE_SETTING_REG);
+
 	/* Set class code */
 	val = readl_relaxed(port->base + PCIE_PCI_IDS_1);
 	val &= ~GENMASK(31, 8);
@@ -872,6 +903,10 @@
 		return port->num_clks;
 	}
 
+	port->max_link_width = of_pci_get_max_link_width(dev->of_node);
+	if (port->max_link_width < 0)
+		dev_err(dev, "failed to get max link width\n");
+
 	return 0;
 }