1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Rockchip Electronics Co. Ltd. 4 * 5 * Author: Wyon Bi <bivvy.bi@rock-chips.com> 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <generic-phy.h> 11 #include <reset.h> 12 #include <asm/io.h> 13 #include <linux/iopoll.h> 14 15 #define HIWORD_UPDATE(x, h, l) ((((x) << (l)) & GENMASK((h), (l))) | \ 16 (GENMASK((h), (l)) << 16)) 17 18 #define EDP_PHY_GRF_CON0 0x0000 19 #define EDP_PHY_TX_IDLE(x) HIWORD_UPDATE(x, 11, 8) 20 #define EDP_PHY_TX_PD(x) HIWORD_UPDATE(x, 7, 4) 21 #define EDP_PHY_IDDQ_EN(x) HIWORD_UPDATE(x, 1, 1) 22 #define EDP_PHY_PD_PLL(x) HIWORD_UPDATE(x, 0, 0) 23 #define EDP_PHY_GRF_CON1 0x0004 24 #define EDP_PHY_PLL_DIV(x) HIWORD_UPDATE(x, 14, 0) 25 #define EDP_PHY_GRF_CON2 0x0008 26 #define EDP_PHY_TX_RTERM(x) HIWORD_UPDATE(x, 10, 8) 27 #define EDP_PHY_RATE(x) HIWORD_UPDATE(x, 5, 4) 28 #define EDP_PHY_REF_DIV(x) HIWORD_UPDATE(x, 3, 0) 29 #define EDP_PHY_GRF_CON3 0x000c 30 #define EDP_PHY_TX_EMP(lane, x) HIWORD_UPDATE(x, 4 * ((lane) + 1) - 1, \ 31 4 * (lane)) 32 #define EDP_PHY_GRF_CON4 0x0010 33 #define EDP_PHY_TX_AMP(lane, x) HIWORD_UPDATE(x, 4 * ((lane) + 1) - 2, \ 34 4 * (lane)) 35 #define EDP_PHY_GRF_CON5 0x0014 36 #define EDP_PHY_TX_MODE(x) HIWORD_UPDATE(x, 9, 8) 37 #define EDP_PHY_TX_AMP_SCALE(lane, x) HIWORD_UPDATE(x, 2 * ((lane) + 1) - 1, \ 38 2 * (lane)) 39 #define EDP_PHY_GRF_CON6 0x0018 40 #define EDP_PHY_SSC_DEPTH(x) HIWORD_UPDATE(x, 15, 12) 41 #define EDP_PHY_SSC_EN(x) HIWORD_UPDATE(x, 11, 11) 42 #define EDP_PHY_SSC_CNT(x) HIWORD_UPDATE(x, 9, 0) 43 #define EDP_PHY_GRF_CON7 0x001c 44 #define EDP_PHY_GRF_CON8 0x0020 45 #define EDP_PHY_PLL_CTL_H(x) HIWORD_UPDATE(x, 15, 0) 46 #define EDP_PHY_GRF_CON9 0x0024 47 #define EDP_PHY_TX_CTL(x) HIWORD_UPDATE(x, 15, 0) 48 #define EDP_PHY_GRF_CON10 0x0028 49 #define EDP_PHY_AUX_RCV_PD_SEL(x) HIWORD_UPDATE(x, 5, 5) 50 #define EDP_PHY_AUX_DRV_PD_SEL(x) HIWORD_UPDATE(x, 4, 4) 51 #define EDP_PHY_AUX_IDLE(x) HIWORD_UPDATE(x, 2, 2) 52 #define EDP_PHY_AUX_RCV_PD(x) HIWORD_UPDATE(x, 1, 1) 53 #define EDP_PHY_AUX_DRV_PD(x) HIWORD_UPDATE(x, 0, 0) 54 #define EDP_PHY_GRF_CON11 0x002c 55 #define EDP_PHY_AUX_RCV_VCM(x) HIWORD_UPDATE(x, 14, 12) 56 #define EDP_PHY_AUX_MODE(x) HIWORD_UPDATE(x, 11, 10) 57 #define EDP_PHY_AUX_AMP_SCALE(x) HIWORD_UPDATE(x, 9, 8) 58 #define EDP_PHY_AUX_AMP(x) HIWORD_UPDATE(x, 6, 4) 59 #define EDP_PHY_AUX_RTERM(x) HIWORD_UPDATE(x, 2, 0) 60 #define EDP_PHY_GRF_STATUS0 0x0030 61 #define PLL_RDY BIT(0) 62 #define EDP_PHY_GRF_STATUS1 0x0034 63 64 struct rockchip_edp_phy { 65 void __iomem *regs; 66 struct udevice *dev; 67 struct reset_ctl apb_reset; 68 }; 69 70 static struct { 71 int amp; 72 int amp_scale; 73 int emp; 74 } vp[4][4] = { 75 { {0x1, 0x1, 0x0}, {0x2, 0x1, 0x4}, {0x3, 0x1, 0x8}, {0x4, 0x1, 0xd} }, 76 { {0x3, 0x1, 0x0}, {0x5, 0x1, 0x7}, {0x6, 0x1, 0x6}, { -1, -1, -1} }, 77 { {0x5, 0x1, 0x0}, {0x7, 0x1, 0x4}, { -1, -1, -1}, { -1, -1, -1} }, 78 { {0x7, 0x1, 0x0}, { -1, -1, -1}, { -1, -1, -1}, { -1, -1, -1} }, 79 }; 80 81 static int rockchip_edp_phy_set_voltages(struct rockchip_edp_phy *edpphy, 82 struct phy_configure_opts_dp *dp) 83 { 84 u8 lane; 85 u32 val; 86 87 for (lane = 0; lane < dp->lanes; lane++) { 88 val = vp[dp->voltage[lane]][dp->pre[lane]].amp; 89 writel(EDP_PHY_TX_AMP(lane, val), 90 edpphy->regs + EDP_PHY_GRF_CON4); 91 92 val = vp[dp->voltage[lane]][dp->pre[lane]].amp_scale; 93 writel(EDP_PHY_TX_AMP_SCALE(lane, val), 94 edpphy->regs + EDP_PHY_GRF_CON5); 95 96 val = vp[dp->voltage[lane]][dp->pre[lane]].emp; 97 writel(EDP_PHY_TX_EMP(lane, val), 98 edpphy->regs + EDP_PHY_GRF_CON3); 99 } 100 101 return 0; 102 } 103 104 static int rockchip_edp_phy_set_rate(struct rockchip_edp_phy *edpphy, 105 struct phy_configure_opts_dp *dp) 106 { 107 u32 value; 108 int ret; 109 110 writel(EDP_PHY_TX_IDLE(0xf) | EDP_PHY_TX_PD(0xf), 111 edpphy->regs + EDP_PHY_GRF_CON0); 112 udelay(100); 113 writel(EDP_PHY_TX_MODE(0x3), edpphy->regs + EDP_PHY_GRF_CON5); 114 writel(EDP_PHY_PD_PLL(0x1), edpphy->regs + EDP_PHY_GRF_CON0); 115 116 switch (dp->link_rate) { 117 case 1620: 118 writel(EDP_PHY_PLL_DIV(0x4380), 119 edpphy->regs + EDP_PHY_GRF_CON1); 120 writel(EDP_PHY_TX_RTERM(0x1) | EDP_PHY_RATE(0x1) | 121 EDP_PHY_REF_DIV(0x0), edpphy->regs + EDP_PHY_GRF_CON2); 122 writel(EDP_PHY_PLL_CTL_H(0x0800), 123 edpphy->regs + EDP_PHY_GRF_CON8); 124 writel(EDP_PHY_TX_CTL(0x0000), edpphy->regs + EDP_PHY_GRF_CON9); 125 break; 126 case 2700: 127 writel(EDP_PHY_PLL_DIV(0x3840), 128 edpphy->regs + EDP_PHY_GRF_CON1); 129 writel(EDP_PHY_TX_RTERM(0x1) | EDP_PHY_RATE(0x0) | 130 EDP_PHY_REF_DIV(0x0), edpphy->regs + EDP_PHY_GRF_CON2); 131 writel(EDP_PHY_PLL_CTL_H(0x0800), 132 edpphy->regs + EDP_PHY_GRF_CON8); 133 writel(EDP_PHY_TX_CTL(0x0000), edpphy->regs + EDP_PHY_GRF_CON9); 134 break; 135 } 136 137 if (dp->ssc) 138 writel(EDP_PHY_SSC_DEPTH(0x9) | EDP_PHY_SSC_EN(0x1) | 139 EDP_PHY_SSC_CNT(0x17d), 140 edpphy->regs + EDP_PHY_GRF_CON6); 141 else 142 writel(EDP_PHY_SSC_EN(0x0), edpphy->regs + EDP_PHY_GRF_CON6); 143 144 writel(EDP_PHY_PD_PLL(0x0), edpphy->regs + EDP_PHY_GRF_CON0); 145 writel(EDP_PHY_TX_PD(~GENMASK(dp->lanes - 1, 0)), 146 edpphy->regs + EDP_PHY_GRF_CON0); 147 ret = readl_poll_timeout(edpphy->regs + EDP_PHY_GRF_STATUS0, 148 value, value & PLL_RDY, 1000); 149 if (ret) { 150 dev_err(edpphy->dev, "pll is not ready: %d\n", ret); 151 return ret; 152 } 153 154 writel(EDP_PHY_TX_MODE(0x0), edpphy->regs + EDP_PHY_GRF_CON5); 155 writel(EDP_PHY_TX_IDLE(~GENMASK(dp->lanes - 1, 0)), 156 edpphy->regs + EDP_PHY_GRF_CON0); 157 158 return 0; 159 } 160 161 static int rockchip_edp_phy_verify_config(struct rockchip_edp_phy *edpphy, 162 struct phy_configure_opts_dp *dp) 163 { 164 int i; 165 166 /* If changing link rate was required, verify it's supported. */ 167 if (dp->set_rate) { 168 switch (dp->link_rate) { 169 case 1620: 170 case 2700: 171 /* valid bit rate */ 172 break; 173 default: 174 return -EINVAL; 175 } 176 } 177 178 /* Verify lane count. */ 179 switch (dp->lanes) { 180 case 1: 181 case 2: 182 case 4: 183 /* valid lane count. */ 184 break; 185 default: 186 return -EINVAL; 187 } 188 189 /* 190 * If changing voltages is required, check swing and pre-emphasis 191 * levels, per-lane. 192 */ 193 if (dp->set_voltages) { 194 /* Lane count verified previously. */ 195 for (i = 0; i < dp->lanes; i++) { 196 if (dp->voltage[i] > 3 || dp->pre[i] > 3) 197 return -EINVAL; 198 199 /* 200 * Sum of voltage swing and pre-emphasis levels cannot 201 * exceed 3. 202 */ 203 if (dp->voltage[i] + dp->pre[i] > 3) 204 return -EINVAL; 205 } 206 } 207 208 return 0; 209 } 210 211 static int rockchip_edp_phy_configure(struct phy *phy, 212 union phy_configure_opts *opts) 213 { 214 struct rockchip_edp_phy *edpphy = dev_get_priv(phy->dev); 215 int ret; 216 217 ret = rockchip_edp_phy_verify_config(edpphy, &opts->dp); 218 if (ret) { 219 dev_err(edpphy->dev, "invalid params for phy configure\n"); 220 return ret; 221 } 222 223 if (opts->dp.set_rate) { 224 ret = rockchip_edp_phy_set_rate(edpphy, &opts->dp); 225 if (ret) { 226 dev_err(edpphy->dev, 227 "rockchip_edp_phy_set_rate failed\n"); 228 return ret; 229 } 230 } 231 232 if (opts->dp.set_voltages) { 233 ret = rockchip_edp_phy_set_voltages(edpphy, &opts->dp); 234 if (ret) { 235 dev_err(edpphy->dev, 236 "rockchip_edp_phy_set_voltages failed\n"); 237 return ret; 238 } 239 } 240 241 return 0; 242 } 243 244 static int rockchip_edp_phy_power_on(struct phy *phy) 245 { 246 struct rockchip_edp_phy *edpphy = dev_get_priv(phy->dev); 247 248 reset_assert(&edpphy->apb_reset); 249 udelay(1); 250 reset_deassert(&edpphy->apb_reset); 251 udelay(1); 252 253 writel(EDP_PHY_AUX_RCV_PD(0x1) | EDP_PHY_AUX_DRV_PD(0x1) | 254 EDP_PHY_AUX_IDLE(0x1), edpphy->regs + EDP_PHY_GRF_CON10); 255 writel(EDP_PHY_TX_IDLE(0xf) | EDP_PHY_TX_PD(0xf) | EDP_PHY_PD_PLL(0x1), 256 edpphy->regs + EDP_PHY_GRF_CON0); 257 udelay(100); 258 259 writel(EDP_PHY_AUX_RCV_VCM(0x4) | EDP_PHY_AUX_MODE(0x1) | 260 EDP_PHY_AUX_AMP_SCALE(0x1) | EDP_PHY_AUX_AMP(0x3) | 261 EDP_PHY_AUX_RTERM(0x1), edpphy->regs + EDP_PHY_GRF_CON11); 262 263 writel(EDP_PHY_AUX_RCV_PD(0x0) | EDP_PHY_AUX_DRV_PD(0x0), 264 edpphy->regs + EDP_PHY_GRF_CON10); 265 udelay(100); 266 267 writel(EDP_PHY_AUX_IDLE(0x0), edpphy->regs + EDP_PHY_GRF_CON10); 268 mdelay(20); 269 270 return 0; 271 } 272 273 static int rockchip_edp_phy_power_off(struct phy *phy) 274 { 275 struct rockchip_edp_phy *edpphy = dev_get_priv(phy->dev); 276 277 writel(EDP_PHY_TX_IDLE(0xf) | EDP_PHY_TX_PD(0xf), 278 edpphy->regs + EDP_PHY_GRF_CON0); 279 udelay(100); 280 writel(EDP_PHY_TX_MODE(0x3), edpphy->regs + EDP_PHY_GRF_CON5); 281 writel(EDP_PHY_PD_PLL(0x1), edpphy->regs + EDP_PHY_GRF_CON0); 282 writel(EDP_PHY_AUX_RCV_PD(0x1) | EDP_PHY_AUX_DRV_PD(0x1) | 283 EDP_PHY_AUX_IDLE(0x1), edpphy->regs + EDP_PHY_GRF_CON10); 284 285 return 0; 286 } 287 288 static struct phy_ops rockchip_edp_phy_ops = { 289 .power_on = rockchip_edp_phy_power_on, 290 .power_off = rockchip_edp_phy_power_off, 291 .configure = rockchip_edp_phy_configure, 292 }; 293 294 static int rockchip_edp_phy_probe(struct udevice *dev) 295 { 296 struct rockchip_edp_phy *edpphy = dev_get_priv(dev); 297 int ret; 298 299 edpphy->regs = dev_read_addr_ptr(dev); 300 if (!edpphy->regs) 301 return -ENOENT; 302 303 edpphy->dev = dev; 304 305 ret = reset_get_by_name(dev, "apb", &edpphy->apb_reset); 306 if (ret < 0) { 307 dev_err(dev, "failed to get apb reset: %d\n", ret); 308 return ret; 309 } 310 311 return 0; 312 } 313 314 static const struct udevice_id rockchip_edp_phy_ids[] = { 315 { .compatible = "rockchip,rk3568-edp-phy", }, 316 {} 317 }; 318 319 U_BOOT_DRIVER(rockchip_edp_phy) = { 320 .name = "rockchip_edp_phy", 321 .id = UCLASS_PHY, 322 .ops = &rockchip_edp_phy_ops, 323 .of_match = rockchip_edp_phy_ids, 324 .probe = rockchip_edp_phy_probe, 325 .priv_auto_alloc_size = sizeof(struct rockchip_edp_phy), 326 }; 327