1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2014, Rockchip Electronics Co., Ltd. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/mfd/syscon.h> 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include <linux/phy/phy.h> 11 #include <linux/regmap.h> 12 #include <linux/regulator/consumer.h> 13 14 #include <drm/bridge/dw_hdmi.h> 15 #include <drm/drm_edid.h> 16 #include <drm/drm_of.h> 17 #include <drm/drm_probe_helper.h> 18 #include <drm/drm_simple_kms_helper.h> 19 20 #include "rockchip_drm_drv.h" 21 22 #define RK3228_GRF_SOC_CON2 0x0408 23 #define RK3228_HDMI_SDAIN_MSK BIT(14) 24 #define RK3228_HDMI_SCLIN_MSK BIT(13) 25 #define RK3228_GRF_SOC_CON6 0x0418 26 #define RK3228_HDMI_HPD_VSEL BIT(6) 27 #define RK3228_HDMI_SDA_VSEL BIT(5) 28 #define RK3228_HDMI_SCL_VSEL BIT(4) 29 30 #define RK3288_GRF_SOC_CON6 0x025C 31 #define RK3288_HDMI_LCDC_SEL BIT(4) 32 #define RK3328_GRF_SOC_CON2 0x0408 33 34 #define RK3328_HDMI_SDAIN_MSK BIT(11) 35 #define RK3328_HDMI_SCLIN_MSK BIT(10) 36 #define RK3328_HDMI_HPD_IOE BIT(2) 37 #define RK3328_GRF_SOC_CON3 0x040c 38 /* need to be unset if hdmi or i2c should control voltage */ 39 #define RK3328_HDMI_SDA5V_GRF BIT(15) 40 #define RK3328_HDMI_SCL5V_GRF BIT(14) 41 #define RK3328_HDMI_HPD5V_GRF BIT(13) 42 #define RK3328_HDMI_CEC5V_GRF BIT(12) 43 #define RK3328_GRF_SOC_CON4 0x0410 44 #define RK3328_HDMI_HPD_SARADC BIT(13) 45 #define RK3328_HDMI_CEC_5V BIT(11) 46 #define RK3328_HDMI_SDA_5V BIT(10) 47 #define RK3328_HDMI_SCL_5V BIT(9) 48 #define RK3328_HDMI_HPD_5V BIT(8) 49 50 #define RK3399_GRF_SOC_CON20 0x6250 51 #define RK3399_HDMI_LCDC_SEL BIT(6) 52 53 #define RK3568_GRF_VO_CON1 0x0364 54 #define RK3568_HDMI_SDAIN_MSK BIT(15) 55 #define RK3568_HDMI_SCLIN_MSK BIT(14) 56 57 #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) 58 59 /** 60 * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips 61 * @lcdsel_grf_reg: grf register offset of lcdc select 62 * @lcdsel_big: reg value of selecting vop big for HDMI 63 * @lcdsel_lit: reg value of selecting vop little for HDMI 64 * @max_tmds_clock: maximum TMDS clock rate supported 65 */ 66 struct rockchip_hdmi_chip_data { 67 int lcdsel_grf_reg; 68 u32 lcdsel_big; 69 u32 lcdsel_lit; 70 int max_tmds_clock; 71 }; 72 73 struct rockchip_hdmi { 74 struct device *dev; 75 struct regmap *regmap; 76 struct rockchip_encoder encoder; 77 const struct rockchip_hdmi_chip_data *chip_data; 78 const struct dw_hdmi_plat_data *plat_data; 79 struct clk *hdmiphy_clk; 80 struct clk *ref_clk; 81 struct clk *grf_clk; 82 struct dw_hdmi *hdmi; 83 struct phy *phy; 84 }; 85 86 static struct rockchip_hdmi *to_rockchip_hdmi(struct drm_encoder *encoder) 87 { 88 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); 89 90 return container_of(rkencoder, struct rockchip_hdmi, encoder); 91 } 92 93 static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { 94 { 95 30666000, { 96 { 0x00b3, 0x0000 }, 97 { 0x2153, 0x0000 }, 98 { 0x40f3, 0x0000 }, 99 }, 100 }, { 101 36800000, { 102 { 0x00b3, 0x0000 }, 103 { 0x2153, 0x0000 }, 104 { 0x40a2, 0x0001 }, 105 }, 106 }, { 107 46000000, { 108 { 0x00b3, 0x0000 }, 109 { 0x2142, 0x0001 }, 110 { 0x40a2, 0x0001 }, 111 }, 112 }, { 113 61333000, { 114 { 0x0072, 0x0001 }, 115 { 0x2142, 0x0001 }, 116 { 0x40a2, 0x0001 }, 117 }, 118 }, { 119 73600000, { 120 { 0x0072, 0x0001 }, 121 { 0x2142, 0x0001 }, 122 { 0x4061, 0x0002 }, 123 }, 124 }, { 125 92000000, { 126 { 0x0072, 0x0001 }, 127 { 0x2145, 0x0002 }, 128 { 0x4061, 0x0002 }, 129 }, 130 }, { 131 122666000, { 132 { 0x0051, 0x0002 }, 133 { 0x2145, 0x0002 }, 134 { 0x4061, 0x0002 }, 135 }, 136 }, { 137 147200000, { 138 { 0x0051, 0x0002 }, 139 { 0x2145, 0x0002 }, 140 { 0x4064, 0x0003 }, 141 }, 142 }, { 143 184000000, { 144 { 0x0051, 0x0002 }, 145 { 0x214c, 0x0003 }, 146 { 0x4064, 0x0003 }, 147 }, 148 }, { 149 226666000, { 150 { 0x0040, 0x0003 }, 151 { 0x214c, 0x0003 }, 152 { 0x4064, 0x0003 }, 153 }, 154 }, { 155 272000000, { 156 { 0x0040, 0x0003 }, 157 { 0x214c, 0x0003 }, 158 { 0x5a64, 0x0003 }, 159 }, 160 }, { 161 340000000, { 162 { 0x0040, 0x0003 }, 163 { 0x3b4c, 0x0003 }, 164 { 0x5a64, 0x0003 }, 165 }, 166 }, { 167 600000000, { 168 { 0x1a40, 0x0003 }, 169 { 0x3b4c, 0x0003 }, 170 { 0x5a64, 0x0003 }, 171 }, 172 }, { 173 ~0UL, { 174 { 0x0000, 0x0000 }, 175 { 0x0000, 0x0000 }, 176 { 0x0000, 0x0000 }, 177 }, 178 } 179 }; 180 181 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { 182 /* pixelclk bpp8 bpp10 bpp12 */ 183 { 184 600000000, { 0x0000, 0x0000, 0x0000 }, 185 }, { 186 ~0UL, { 0x0000, 0x0000, 0x0000 }, 187 } 188 }; 189 190 static const struct dw_hdmi_phy_config rockchip_phy_config[] = { 191 /*pixelclk symbol term vlev*/ 192 { 74250000, 0x8009, 0x0004, 0x0272}, 193 { 165000000, 0x802b, 0x0004, 0x0209}, 194 { 297000000, 0x8039, 0x0005, 0x028d}, 195 { 594000000, 0x8039, 0x0000, 0x019d}, 196 { ~0UL, 0x0000, 0x0000, 0x0000} 197 }; 198 199 static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) 200 { 201 struct device_node *np = hdmi->dev->of_node; 202 int ret; 203 204 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 205 if (IS_ERR(hdmi->regmap)) { 206 dev_err(hdmi->dev, "Unable to get rockchip,grf\n"); 207 return PTR_ERR(hdmi->regmap); 208 } 209 210 hdmi->ref_clk = devm_clk_get_optional_enabled(hdmi->dev, "ref"); 211 if (!hdmi->ref_clk) 212 hdmi->ref_clk = devm_clk_get_optional_enabled(hdmi->dev, "vpll"); 213 214 if (IS_ERR(hdmi->ref_clk)) { 215 ret = PTR_ERR(hdmi->ref_clk); 216 return dev_err_probe(hdmi->dev, ret, "failed to get reference clock\n"); 217 } 218 219 hdmi->grf_clk = devm_clk_get_optional(hdmi->dev, "grf"); 220 if (IS_ERR(hdmi->grf_clk)) { 221 ret = PTR_ERR(hdmi->grf_clk); 222 return dev_err_probe(hdmi->dev, ret, "failed to get grf clock\n"); 223 } 224 225 ret = devm_regulator_get_enable(hdmi->dev, "avdd-0v9"); 226 if (ret) 227 return ret; 228 229 ret = devm_regulator_get_enable(hdmi->dev, "avdd-1v8"); 230 231 return ret; 232 } 233 234 static enum drm_mode_status 235 dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, 236 const struct drm_display_info *info, 237 const struct drm_display_mode *mode) 238 { 239 struct rockchip_hdmi *hdmi = data; 240 int pclk = mode->clock * 1000; 241 242 if (hdmi->chip_data->max_tmds_clock && 243 mode->clock > hdmi->chip_data->max_tmds_clock) 244 return MODE_CLOCK_HIGH; 245 246 if (hdmi->ref_clk) { 247 int rpclk = clk_round_rate(hdmi->ref_clk, pclk); 248 249 if (rpclk < 0 || abs(rpclk - pclk) > pclk / 1000) 250 return MODE_NOCLOCK; 251 } 252 253 if (hdmi->hdmiphy_clk) { 254 int rpclk = clk_round_rate(hdmi->hdmiphy_clk, pclk); 255 256 if (rpclk < 0 || abs(rpclk - pclk) > pclk / 1000) 257 return MODE_NOCLOCK; 258 } 259 260 return MODE_OK; 261 } 262 263 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) 264 { 265 } 266 267 static bool 268 dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder, 269 const struct drm_display_mode *mode, 270 struct drm_display_mode *adj_mode) 271 { 272 return true; 273 } 274 275 static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder, 276 struct drm_display_mode *mode, 277 struct drm_display_mode *adj_mode) 278 { 279 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); 280 281 clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000); 282 } 283 284 static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) 285 { 286 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); 287 u32 val; 288 int ret; 289 290 if (hdmi->chip_data->lcdsel_grf_reg < 0) 291 return; 292 293 ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder); 294 if (ret) 295 val = hdmi->chip_data->lcdsel_lit; 296 else 297 val = hdmi->chip_data->lcdsel_big; 298 299 ret = clk_prepare_enable(hdmi->grf_clk); 300 if (ret < 0) { 301 dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret); 302 return; 303 } 304 305 ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val); 306 if (ret != 0) 307 dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret); 308 309 clk_disable_unprepare(hdmi->grf_clk); 310 dev_dbg(hdmi->dev, "vop %s output to hdmi\n", ret ? "LIT" : "BIG"); 311 } 312 313 static int 314 dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, 315 struct drm_crtc_state *crtc_state, 316 struct drm_connector_state *conn_state) 317 { 318 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 319 320 s->output_mode = ROCKCHIP_OUT_MODE_AAAA; 321 s->output_type = DRM_MODE_CONNECTOR_HDMIA; 322 323 return 0; 324 } 325 326 static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = { 327 .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup, 328 .mode_set = dw_hdmi_rockchip_encoder_mode_set, 329 .enable = dw_hdmi_rockchip_encoder_enable, 330 .disable = dw_hdmi_rockchip_encoder_disable, 331 .atomic_check = dw_hdmi_rockchip_encoder_atomic_check, 332 }; 333 334 static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, 335 const struct drm_display_info *display, 336 const struct drm_display_mode *mode) 337 { 338 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; 339 340 dw_hdmi_set_high_tmds_clock_ratio(dw_hdmi, display); 341 342 return phy_power_on(hdmi->phy); 343 } 344 345 static void dw_hdmi_rockchip_genphy_disable(struct dw_hdmi *dw_hdmi, void *data) 346 { 347 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; 348 349 phy_power_off(hdmi->phy); 350 } 351 352 static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data) 353 { 354 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; 355 356 dw_hdmi_phy_setup_hpd(dw_hdmi, data); 357 358 regmap_write(hdmi->regmap, 359 RK3228_GRF_SOC_CON6, 360 HIWORD_UPDATE(RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL | 361 RK3228_HDMI_SCL_VSEL, 362 RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL | 363 RK3228_HDMI_SCL_VSEL)); 364 365 regmap_write(hdmi->regmap, 366 RK3228_GRF_SOC_CON2, 367 HIWORD_UPDATE(RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK, 368 RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK)); 369 } 370 371 static enum drm_connector_status 372 dw_hdmi_rk3328_read_hpd(struct dw_hdmi *dw_hdmi, void *data) 373 { 374 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; 375 enum drm_connector_status status; 376 377 status = dw_hdmi_phy_read_hpd(dw_hdmi, data); 378 379 if (status == connector_status_connected) 380 regmap_write(hdmi->regmap, 381 RK3328_GRF_SOC_CON4, 382 HIWORD_UPDATE(RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V, 383 RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V)); 384 else 385 regmap_write(hdmi->regmap, 386 RK3328_GRF_SOC_CON4, 387 HIWORD_UPDATE(0, RK3328_HDMI_SDA_5V | 388 RK3328_HDMI_SCL_5V)); 389 return status; 390 } 391 392 static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data) 393 { 394 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; 395 396 dw_hdmi_phy_setup_hpd(dw_hdmi, data); 397 398 /* Enable and map pins to 3V grf-controlled io-voltage */ 399 regmap_write(hdmi->regmap, 400 RK3328_GRF_SOC_CON4, 401 HIWORD_UPDATE(0, RK3328_HDMI_HPD_SARADC | RK3328_HDMI_CEC_5V | 402 RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V | 403 RK3328_HDMI_HPD_5V)); 404 regmap_write(hdmi->regmap, 405 RK3328_GRF_SOC_CON3, 406 HIWORD_UPDATE(0, RK3328_HDMI_SDA5V_GRF | RK3328_HDMI_SCL5V_GRF | 407 RK3328_HDMI_HPD5V_GRF | 408 RK3328_HDMI_CEC5V_GRF)); 409 regmap_write(hdmi->regmap, 410 RK3328_GRF_SOC_CON2, 411 HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK, 412 RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK | 413 RK3328_HDMI_HPD_IOE)); 414 415 dw_hdmi_rk3328_read_hpd(dw_hdmi, data); 416 } 417 418 static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { 419 .init = dw_hdmi_rockchip_genphy_init, 420 .disable = dw_hdmi_rockchip_genphy_disable, 421 .read_hpd = dw_hdmi_phy_read_hpd, 422 .update_hpd = dw_hdmi_phy_update_hpd, 423 .setup_hpd = dw_hdmi_rk3228_setup_hpd, 424 }; 425 426 static struct rockchip_hdmi_chip_data rk3228_chip_data = { 427 .lcdsel_grf_reg = -1, 428 .max_tmds_clock = 594000, 429 }; 430 431 static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { 432 .mode_valid = dw_hdmi_rockchip_mode_valid, 433 .phy_data = &rk3228_chip_data, 434 .phy_ops = &rk3228_hdmi_phy_ops, 435 .phy_name = "inno_dw_hdmi_phy2", 436 .phy_force_vendor = true, 437 }; 438 439 static struct rockchip_hdmi_chip_data rk3288_chip_data = { 440 .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, 441 .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL), 442 .lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL), 443 .max_tmds_clock = 340000, 444 }; 445 446 static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = { 447 .mode_valid = dw_hdmi_rockchip_mode_valid, 448 .mpll_cfg = rockchip_mpll_cfg, 449 .cur_ctr = rockchip_cur_ctr, 450 .phy_config = rockchip_phy_config, 451 .phy_data = &rk3288_chip_data, 452 }; 453 454 static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = { 455 .init = dw_hdmi_rockchip_genphy_init, 456 .disable = dw_hdmi_rockchip_genphy_disable, 457 .read_hpd = dw_hdmi_rk3328_read_hpd, 458 .update_hpd = dw_hdmi_phy_update_hpd, 459 .setup_hpd = dw_hdmi_rk3328_setup_hpd, 460 }; 461 462 static struct rockchip_hdmi_chip_data rk3328_chip_data = { 463 .lcdsel_grf_reg = -1, 464 .max_tmds_clock = 594000, 465 }; 466 467 static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { 468 .mode_valid = dw_hdmi_rockchip_mode_valid, 469 .phy_data = &rk3328_chip_data, 470 .phy_ops = &rk3328_hdmi_phy_ops, 471 .phy_name = "inno_dw_hdmi_phy2", 472 .phy_force_vendor = true, 473 .use_drm_infoframe = true, 474 }; 475 476 static struct rockchip_hdmi_chip_data rk3399_chip_data = { 477 .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, 478 .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL), 479 .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL), 480 .max_tmds_clock = 594000, 481 }; 482 483 static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { 484 .mode_valid = dw_hdmi_rockchip_mode_valid, 485 .mpll_cfg = rockchip_mpll_cfg, 486 .cur_ctr = rockchip_cur_ctr, 487 .phy_config = rockchip_phy_config, 488 .phy_data = &rk3399_chip_data, 489 .use_drm_infoframe = true, 490 }; 491 492 static struct rockchip_hdmi_chip_data rk3568_chip_data = { 493 .lcdsel_grf_reg = -1, 494 .max_tmds_clock = 594000, 495 }; 496 497 static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = { 498 .mode_valid = dw_hdmi_rockchip_mode_valid, 499 .mpll_cfg = rockchip_mpll_cfg, 500 .cur_ctr = rockchip_cur_ctr, 501 .phy_config = rockchip_phy_config, 502 .phy_data = &rk3568_chip_data, 503 .use_drm_infoframe = true, 504 }; 505 506 static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = { 507 { .compatible = "rockchip,rk3228-dw-hdmi", 508 .data = &rk3228_hdmi_drv_data 509 }, 510 { .compatible = "rockchip,rk3288-dw-hdmi", 511 .data = &rk3288_hdmi_drv_data 512 }, 513 { .compatible = "rockchip,rk3328-dw-hdmi", 514 .data = &rk3328_hdmi_drv_data 515 }, 516 { .compatible = "rockchip,rk3399-dw-hdmi", 517 .data = &rk3399_hdmi_drv_data 518 }, 519 { .compatible = "rockchip,rk3568-dw-hdmi", 520 .data = &rk3568_hdmi_drv_data 521 }, 522 {}, 523 }; 524 MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids); 525 526 static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, 527 void *data) 528 { 529 struct platform_device *pdev = to_platform_device(dev); 530 struct dw_hdmi_plat_data *plat_data; 531 const struct of_device_id *match; 532 struct drm_device *drm = data; 533 struct drm_encoder *encoder; 534 struct rockchip_hdmi *hdmi; 535 int ret; 536 537 if (!pdev->dev.of_node) 538 return -ENODEV; 539 540 hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); 541 if (!hdmi) 542 return -ENOMEM; 543 544 match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node); 545 plat_data = devm_kmemdup(&pdev->dev, match->data, 546 sizeof(*plat_data), GFP_KERNEL); 547 if (!plat_data) 548 return -ENOMEM; 549 550 hdmi->dev = &pdev->dev; 551 hdmi->plat_data = plat_data; 552 hdmi->chip_data = plat_data->phy_data; 553 plat_data->phy_data = hdmi; 554 plat_data->priv_data = hdmi; 555 encoder = &hdmi->encoder.encoder; 556 557 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); 558 rockchip_drm_encoder_set_crtc_endpoint_id(&hdmi->encoder, 559 dev->of_node, 0, 0); 560 561 /* 562 * If we failed to find the CRTC(s) which this encoder is 563 * supposed to be connected to, it's because the CRTC has 564 * not been registered yet. Defer probing, and hope that 565 * the required CRTC is added later. 566 */ 567 if (encoder->possible_crtcs == 0) 568 return -EPROBE_DEFER; 569 570 ret = rockchip_hdmi_parse_dt(hdmi); 571 if (ret) { 572 return dev_err_probe(hdmi->dev, ret, "Unable to parse OF data\n"); 573 } 574 575 hdmi->phy = devm_phy_optional_get(dev, "hdmi"); 576 if (IS_ERR(hdmi->phy)) { 577 ret = PTR_ERR(hdmi->phy); 578 return dev_err_probe(hdmi->dev, ret, "failed to get phy\n"); 579 } 580 581 if (hdmi->phy) { 582 struct of_phandle_args clkspec; 583 584 clkspec.np = hdmi->phy->dev.of_node; 585 hdmi->hdmiphy_clk = of_clk_get_from_provider(&clkspec); 586 if (IS_ERR(hdmi->hdmiphy_clk)) 587 hdmi->hdmiphy_clk = NULL; 588 } 589 590 if (hdmi->chip_data == &rk3568_chip_data) { 591 regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1, 592 HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK | 593 RK3568_HDMI_SCLIN_MSK, 594 RK3568_HDMI_SDAIN_MSK | 595 RK3568_HDMI_SCLIN_MSK)); 596 } 597 598 drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); 599 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); 600 601 platform_set_drvdata(pdev, hdmi); 602 603 hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); 604 605 /* 606 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), 607 * which would have called the encoder cleanup. Do it manually. 608 */ 609 if (IS_ERR(hdmi->hdmi)) { 610 ret = PTR_ERR(hdmi->hdmi); 611 goto err_bind; 612 } 613 614 return 0; 615 616 err_bind: 617 drm_encoder_cleanup(encoder); 618 619 return ret; 620 } 621 622 static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, 623 void *data) 624 { 625 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); 626 627 dw_hdmi_unbind(hdmi->hdmi); 628 drm_encoder_cleanup(&hdmi->encoder.encoder); 629 } 630 631 static const struct component_ops dw_hdmi_rockchip_ops = { 632 .bind = dw_hdmi_rockchip_bind, 633 .unbind = dw_hdmi_rockchip_unbind, 634 }; 635 636 static int dw_hdmi_rockchip_probe(struct platform_device *pdev) 637 { 638 return component_add(&pdev->dev, &dw_hdmi_rockchip_ops); 639 } 640 641 static void dw_hdmi_rockchip_remove(struct platform_device *pdev) 642 { 643 component_del(&pdev->dev, &dw_hdmi_rockchip_ops); 644 } 645 646 static int __maybe_unused dw_hdmi_rockchip_resume(struct device *dev) 647 { 648 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); 649 650 dw_hdmi_resume(hdmi->hdmi); 651 652 return 0; 653 } 654 655 static const struct dev_pm_ops dw_hdmi_rockchip_pm = { 656 SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_rockchip_resume) 657 }; 658 659 struct platform_driver dw_hdmi_rockchip_pltfm_driver = { 660 .probe = dw_hdmi_rockchip_probe, 661 .remove = dw_hdmi_rockchip_remove, 662 .driver = { 663 .name = "dwhdmi-rockchip", 664 .pm = &dw_hdmi_rockchip_pm, 665 .of_match_table = dw_hdmi_rockchip_dt_ids, 666 }, 667 }; 668