From 91802f44a959582842bdbbd0190e68337ad4c60c Mon Sep 17 00:00:00 2001
From: Kever Yang <kever.yang@rock-chips.com>
Date: Mon, 11 Jul 2022 20:35:52 +0800
Subject: [PATCH] phy: rockchip-snps-pcie3: rk3568: update fw when init

This fw fix some RX issue:
1. connect detect error;
2. transfer error in ssd huge data write(more than 10GB).

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Change-Id: I6624b6af2ede3c2fca61c0f753a08a33ce69a6d2
---
 drivers/phy/phy-rockchip-snps-pcie3.c  |   36 +-
 drivers/phy/phy-rockchip-snps-pcie3.fw | 8192 ++++++++++++++++++++++++
 2 files changed, 8225 insertions(+), 3 deletions(-)
 create mode 100644 drivers/phy/phy-rockchip-snps-pcie3.fw

--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
@@ -21,6 +21,7 @@
 
 /* Register for RK3568 */
 #define GRF_PCIE30PHY_CON1			0x4
+#define GRF_PCIE30PHY_CON4			0x10
 #define GRF_PCIE30PHY_CON6			0x18
 #define GRF_PCIE30PHY_CON9			0x24
 #define GRF_PCIE30PHY_DA_OCM			(BIT(15) | BIT(31))
@@ -73,6 +74,10 @@ struct rockchip_p3phy_ops {
 	int (*phy_init)(struct rockchip_p3phy_priv *priv);
 };
 
+static u16 phy_fw[] = {
+	#include "p3phy.fw"
+};
+
 static int rockchip_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 {
 	struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
@@ -97,13 +102,14 @@ static int rockchip_p3phy_rk3568_init(st
 {
 	struct phy *phy = priv->phy;
 	bool bifurcation = false;
+	int i;
 	int ret;
 	u32 reg;
 
 	/* Deassert PCIe PMA output clamp mode */
 	regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, GRF_PCIE30PHY_DA_OCM);
 
-	for (int i = 0; i < priv->num_lanes; i++) {
+	for (i = 0; i < priv->num_lanes; i++) {
 		dev_info(&phy->dev, "lane number %d, val %d\n", i, priv->lanes[i]);
 		if (priv->lanes[i] > 1)
 			bifurcation = true;
@@ -122,16 +128,35 @@ static int rockchip_p3phy_rk3568_init(st
 			     GRF_PCIE30PHY_WR_EN & ~RK3568_BIFURCATION_LANE_0_1);
 	}
 
+	regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4,
+		     (0x0 << 14) | (0x1 << (14 + 16))); //sdram_ld_done
+	regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4,
+		     (0x0 << 13) | (0x1 << (13 + 16))); //sdram_bypass
+
 	reset_control_deassert(priv->p30phy);
 
 	ret = regmap_read_poll_timeout(priv->phy_grf,
 				       GRF_PCIE30PHY_STATUS0,
 				       reg, SRAM_INIT_DONE(reg),
 				       0, 500);
-	if (ret)
+	if (ret) {
 		dev_err(&priv->phy->dev, "%s: lock failed 0x%x, check input refclk and power supply\n",
 		       __func__, reg);
-	return ret;
+		return ret;
+	}
+
+	regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9,
+		     (0x3 << 8) | (0x3 << (8 + 16))); //map to access sram
+	for (i = 0; i < 8192; i++)
+		writel(phy_fw[i], priv->mmio + (i<<2));
+
+	regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9,
+		     (0x0 << 8) | (0x3 << (8 + 16)));
+	regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4,
+		     (0x1 << 14) | (0x1 << (14 + 16))); //sdram_ld_done
+
+	dev_info(&priv->phy->dev, "p3phy (fw-d54d0eb) initialized\n");
+	return 0;
 }
 
 static const struct rockchip_p3phy_ops rk3568_ops = {
