1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Rockchip PCIE3.0 phy driver 4 * 5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd. 6 */ 7 8#include <common.h> 9#include <clk.h> 10#include <dm.h> 11#include <generic-phy.h> 12#include <regmap.h> 13#include <reset-uclass.h> 14#include <syscon.h> 15#include <asm/io.h> 16#include <dm/device_compat.h> 17#include <dm/lists.h> 18 19/* Register for RK3568 */ 20#define GRF_PCIE30PHY_CON1 0x4 21#define GRF_PCIE30PHY_CON6 0x18 22#define GRF_PCIE30PHY_CON9 0x24 23#define GRF_PCIE30PHY_DA_OCM (BIT(15) | BIT(31)) 24#define GRF_PCIE30PHY_STATUS0 0x80 25#define GRF_PCIE30PHY_WR_EN (0xf << 16) 26#define SRAM_INIT_DONE(reg) (reg & BIT(14)) 27 28#define RK3568_BIFURCATION_LANE_0_1 BIT(0) 29 30/* Register for RK3588 */ 31#define PHP_GRF_PCIESEL_CON 0x100 32#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 33#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 34#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 35#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0)) 36 37#define RK3588_BIFURCATION_LANE_0_1 BIT(0) 38#define RK3588_BIFURCATION_LANE_2_3 BIT(1) 39#define RK3588_LANE_AGGREGATION BIT(2) 40 41/** 42 * struct rockchip_p3phy_priv - RK DW PCIe PHY state 43 * 44 * @mmio: The base address of PHY internal registers 45 * @phy_grf: The regmap for controlling pipe signal 46 * @p30phy: The reset signal for PHY 47 * @clks: The clocks for PHY 48 * @num_lanes: The number of lane to controller mappings 49 * @lanes: The lane to controller mapping 50 */ 51struct rockchip_p3phy_priv { 52 void __iomem *mmio; 53 struct regmap *phy_grf; 54 struct regmap *pipe_grf; 55 struct reset_ctl p30phy; 56 struct clk_bulk clks; 57 int num_lanes; 58 u32 lanes[4]; 59}; 60 61struct rockchip_p3phy_ops { 62 int (*phy_init)(struct phy *phy); 63}; 64 65static int rockchip_p3phy_rk3568_init(struct phy *phy) 66{ 67 struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); 68 bool bifurcation = false; 69 int ret; 70 u32 reg; 71 72 /* Deassert PCIe PMA output clamp mode */ 73 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, GRF_PCIE30PHY_DA_OCM); 74 75 for (int i = 0; i < priv->num_lanes; i++) { 76 if (priv->lanes[i] > 1) 77 bifurcation = true; 78 } 79 80 /* Set bifurcation if needed, and it doesn't care RC/EP */ 81 if (bifurcation) { 82 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, 83 GRF_PCIE30PHY_WR_EN | RK3568_BIFURCATION_LANE_0_1); 84 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON1, 85 GRF_PCIE30PHY_DA_OCM); 86 } else { 87 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, 88 GRF_PCIE30PHY_WR_EN & ~RK3568_BIFURCATION_LANE_0_1); 89 } 90 91 reset_deassert(&priv->p30phy); 92 udelay(1); 93 94 ret = regmap_read_poll_timeout(priv->phy_grf, 95 GRF_PCIE30PHY_STATUS0, 96 reg, SRAM_INIT_DONE(reg), 97 0, 500); 98 if (ret) 99 dev_err(phy->dev, "lock failed 0x%x\n", reg); 100 101 return ret; 102} 103 104static const struct rockchip_p3phy_ops rk3568_ops = { 105 .phy_init = rockchip_p3phy_rk3568_init, 106}; 107 108static int rockchip_p3phy_rk3588_init(struct phy *phy) 109{ 110 struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); 111 u32 reg = 0; 112 u8 mode = 0; 113 int ret; 114 115 /* Deassert PCIe PMA output clamp mode */ 116 regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, 117 BIT(8) | BIT(24)); 118 119 /* Set bifurcation if needed */ 120 for (int i = 0; i < priv->num_lanes; i++) { 121 if (!priv->lanes[i]) 122 mode |= (BIT(i) << 3); 123 124 if (priv->lanes[i] > 1) 125 mode |= (BIT(i) >> 1); 126 } 127 128 if (!mode) { 129 reg = RK3588_LANE_AGGREGATION; 130 } else { 131 if (mode & (BIT(0) | BIT(1))) 132 reg |= RK3588_BIFURCATION_LANE_0_1; 133 134 if (mode & (BIT(2) | BIT(3))) 135 reg |= RK3588_BIFURCATION_LANE_2_3; 136 } 137 138 regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, 139 (0x7 << 16) | reg); 140 141 /* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */ 142 reg = (mode & (BIT(6) | BIT(7))) >> 6; 143 if (reg) 144 regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, 145 (reg << 16) | reg); 146 147 reset_deassert(&priv->p30phy); 148 udelay(1); 149 150 ret = regmap_read_poll_timeout(priv->phy_grf, 151 RK3588_PCIE3PHY_GRF_PHY0_STATUS1, 152 reg, RK3588_SRAM_INIT_DONE(reg), 153 0, 500); 154 ret |= regmap_read_poll_timeout(priv->phy_grf, 155 RK3588_PCIE3PHY_GRF_PHY1_STATUS1, 156 reg, RK3588_SRAM_INIT_DONE(reg), 157 0, 500); 158 if (ret) 159 dev_err(phy->dev, "lock failed 0x%x\n", reg); 160 161 return ret; 162} 163 164static const struct rockchip_p3phy_ops rk3588_ops = { 165 .phy_init = rockchip_p3phy_rk3588_init, 166}; 167 168static int rochchip_p3phy_init(struct phy *phy) 169{ 170 struct rockchip_p3phy_ops *ops = 171 (struct rockchip_p3phy_ops *)dev_get_driver_data(phy->dev); 172 struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); 173 int ret; 174 175 ret = clk_enable_bulk(&priv->clks); 176 if (ret) 177 return ret; 178 179 reset_assert(&priv->p30phy); 180 udelay(1); 181 182 ret = ops->phy_init(phy); 183 if (ret) 184 clk_disable_bulk(&priv->clks); 185 186 return ret; 187} 188 189static int rochchip_p3phy_exit(struct phy *phy) 190{ 191 struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); 192 193 clk_disable_bulk(&priv->clks); 194 reset_assert(&priv->p30phy); 195 196 return 0; 197} 198 199static int rockchip_p3phy_probe(struct udevice *dev) 200{ 201 struct rockchip_p3phy_priv *priv = dev_get_priv(dev); 202 int ret; 203 204 priv->mmio = dev_read_addr_ptr(dev); 205 if (!priv->mmio) 206 return -EINVAL; 207 208 priv->phy_grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,phy-grf"); 209 if (IS_ERR(priv->phy_grf)) { 210 dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); 211 return PTR_ERR(priv->phy_grf); 212 } 213 214 if (device_is_compatible(dev, "rockchip,rk3588-pcie3-phy")) { 215 priv->pipe_grf = 216 syscon_regmap_lookup_by_phandle(dev, "rockchip,pipe-grf"); 217 if (IS_ERR(priv->pipe_grf)) { 218 dev_err(dev, "failed to find rockchip,pipe_grf regmap\n"); 219 return PTR_ERR(priv->pipe_grf); 220 } 221 } 222 223 ret = dev_read_size(dev, "data-lanes"); 224 if (ret > 0) { 225 priv->num_lanes = ret / sizeof(u32); 226 if (priv->num_lanes < 2 || 227 priv->num_lanes > ARRAY_SIZE(priv->lanes)) { 228 dev_err(dev, "unsupported data-lanes property size\n"); 229 return -EINVAL; 230 } 231 232 ret = dev_read_u32_array(dev, "data-lanes", priv->lanes, 233 priv->num_lanes); 234 if (ret) { 235 dev_err(dev, "failed to read data-lanes property\n"); 236 return ret; 237 } 238 } 239 240 ret = reset_get_by_name(dev, "phy", &priv->p30phy); 241 if (ret) { 242 dev_err(dev, "no phy reset control specified\n"); 243 return ret; 244 } 245 246 ret = clk_get_bulk(dev, &priv->clks); 247 if (ret) { 248 dev_err(dev, "failed to get clocks\n"); 249 return ret; 250 } 251 252 return 0; 253} 254 255static struct phy_ops rochchip_p3phy_ops = { 256 .init = rochchip_p3phy_init, 257 .exit = rochchip_p3phy_exit, 258}; 259 260static const struct udevice_id rockchip_p3phy_of_match[] = { 261 { 262 .compatible = "rockchip,rk3568-pcie3-phy", 263 .data = (ulong)&rk3568_ops, 264 }, 265 { 266 .compatible = "rockchip,rk3588-pcie3-phy", 267 .data = (ulong)&rk3588_ops, 268 }, 269 { }, 270}; 271 272U_BOOT_DRIVER(rockchip_pcie3phy) = { 273 .name = "rockchip_pcie3phy", 274 .id = UCLASS_PHY, 275 .of_match = rockchip_p3phy_of_match, 276 .ops = &rochchip_p3phy_ops, 277 .probe = rockchip_p3phy_probe, 278 .priv_auto = sizeof(struct rockchip_p3phy_priv), 279}; 280