1 /* 2 * Copyright (C) 2016 Broadcom 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 as published by 6 * the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 /** 18 * DOC: VC4 SDTV module 19 */ 20 21 #include <drm/drm_atomic_helper.h> 22 #include <drm/drm_crtc_helper.h> 23 #include <drm/drm_edid.h> 24 #include <drm/drm_panel.h> 25 #include <linux/clk.h> 26 #include <linux/component.h> 27 #include <linux/of_graph.h> 28 #include <linux/of_platform.h> 29 #include <linux/pm_runtime.h> 30 31 #include "vc4_drv.h" 32 #include "vc4_regs.h" 33 34 /* WSE Registers */ 35 #define VEC_WSE_RESET 0xc0 36 37 #define VEC_WSE_CONTROL 0xc4 38 #define VEC_WSE_WSS_ENABLE BIT(7) 39 40 #define VEC_WSE_WSS_DATA 0xc8 41 #define VEC_WSE_VPS_DATA1 0xcc 42 #define VEC_WSE_VPS_CONTROL 0xd0 43 44 /* VEC Registers */ 45 #define VEC_REVID 0x100 46 47 #define VEC_CONFIG0 0x104 48 #define VEC_CONFIG0_YDEL_MASK GENMASK(28, 26) 49 #define VEC_CONFIG0_YDEL(x) ((x) << 26) 50 #define VEC_CONFIG0_CDEL_MASK GENMASK(25, 24) 51 #define VEC_CONFIG0_CDEL(x) ((x) << 24) 52 #define VEC_CONFIG0_PBPR_FIL BIT(18) 53 #define VEC_CONFIG0_CHROMA_GAIN_MASK GENMASK(17, 16) 54 #define VEC_CONFIG0_CHROMA_GAIN_UNITY (0 << 16) 55 #define VEC_CONFIG0_CHROMA_GAIN_1_32 (1 << 16) 56 #define VEC_CONFIG0_CHROMA_GAIN_1_16 (2 << 16) 57 #define VEC_CONFIG0_CHROMA_GAIN_1_8 (3 << 16) 58 #define VEC_CONFIG0_CBURST_GAIN_MASK GENMASK(14, 13) 59 #define VEC_CONFIG0_CBURST_GAIN_UNITY (0 << 13) 60 #define VEC_CONFIG0_CBURST_GAIN_1_128 (1 << 13) 61 #define VEC_CONFIG0_CBURST_GAIN_1_64 (2 << 13) 62 #define VEC_CONFIG0_CBURST_GAIN_1_32 (3 << 13) 63 #define VEC_CONFIG0_CHRBW1 BIT(11) 64 #define VEC_CONFIG0_CHRBW0 BIT(10) 65 #define VEC_CONFIG0_SYNCDIS BIT(9) 66 #define VEC_CONFIG0_BURDIS BIT(8) 67 #define VEC_CONFIG0_CHRDIS BIT(7) 68 #define VEC_CONFIG0_PDEN BIT(6) 69 #define VEC_CONFIG0_YCDELAY BIT(4) 70 #define VEC_CONFIG0_RAMPEN BIT(2) 71 #define VEC_CONFIG0_YCDIS BIT(2) 72 #define VEC_CONFIG0_STD_MASK GENMASK(1, 0) 73 #define VEC_CONFIG0_NTSC_STD 0 74 #define VEC_CONFIG0_PAL_BDGHI_STD 1 75 #define VEC_CONFIG0_PAL_N_STD 3 76 77 #define VEC_SCHPH 0x108 78 #define VEC_SOFT_RESET 0x10c 79 #define VEC_CLMP0_START 0x144 80 #define VEC_CLMP0_END 0x148 81 #define VEC_FREQ3_2 0x180 82 #define VEC_FREQ1_0 0x184 83 84 #define VEC_CONFIG1 0x188 85 #define VEC_CONFIG_VEC_RESYNC_OFF BIT(18) 86 #define VEC_CONFIG_RGB219 BIT(17) 87 #define VEC_CONFIG_CBAR_EN BIT(16) 88 #define VEC_CONFIG_TC_OBB BIT(15) 89 #define VEC_CONFIG1_OUTPUT_MODE_MASK GENMASK(12, 10) 90 #define VEC_CONFIG1_C_Y_CVBS (0 << 10) 91 #define VEC_CONFIG1_CVBS_Y_C (1 << 10) 92 #define VEC_CONFIG1_PR_Y_PB (2 << 10) 93 #define VEC_CONFIG1_RGB (4 << 10) 94 #define VEC_CONFIG1_Y_C_CVBS (5 << 10) 95 #define VEC_CONFIG1_C_CVBS_Y (6 << 10) 96 #define VEC_CONFIG1_C_CVBS_CVBS (7 << 10) 97 #define VEC_CONFIG1_DIS_CHR BIT(9) 98 #define VEC_CONFIG1_DIS_LUMA BIT(8) 99 #define VEC_CONFIG1_YCBCR_IN BIT(6) 100 #define VEC_CONFIG1_DITHER_TYPE_LFSR 0 101 #define VEC_CONFIG1_DITHER_TYPE_COUNTER BIT(5) 102 #define VEC_CONFIG1_DITHER_EN BIT(4) 103 #define VEC_CONFIG1_CYDELAY BIT(3) 104 #define VEC_CONFIG1_LUMADIS BIT(2) 105 #define VEC_CONFIG1_COMPDIS BIT(1) 106 #define VEC_CONFIG1_CUSTOM_FREQ BIT(0) 107 108 #define VEC_CONFIG2 0x18c 109 #define VEC_CONFIG2_PROG_SCAN BIT(15) 110 #define VEC_CONFIG2_SYNC_ADJ_MASK GENMASK(14, 12) 111 #define VEC_CONFIG2_SYNC_ADJ(x) (((x) / 2) << 12) 112 #define VEC_CONFIG2_PBPR_EN BIT(10) 113 #define VEC_CONFIG2_UV_DIG_DIS BIT(6) 114 #define VEC_CONFIG2_RGB_DIG_DIS BIT(5) 115 #define VEC_CONFIG2_TMUX_MASK GENMASK(3, 2) 116 #define VEC_CONFIG2_TMUX_DRIVE0 (0 << 2) 117 #define VEC_CONFIG2_TMUX_RG_COMP (1 << 2) 118 #define VEC_CONFIG2_TMUX_UV_YC (2 << 2) 119 #define VEC_CONFIG2_TMUX_SYNC_YC (3 << 2) 120 121 #define VEC_INTERRUPT_CONTROL 0x190 122 #define VEC_INTERRUPT_STATUS 0x194 123 #define VEC_FCW_SECAM_B 0x198 124 #define VEC_SECAM_GAIN_VAL 0x19c 125 126 #define VEC_CONFIG3 0x1a0 127 #define VEC_CONFIG3_HORIZ_LEN_STD (0 << 0) 128 #define VEC_CONFIG3_HORIZ_LEN_MPEG1_SIF (1 << 0) 129 #define VEC_CONFIG3_SHAPE_NON_LINEAR BIT(1) 130 131 #define VEC_STATUS0 0x200 132 #define VEC_MASK0 0x204 133 134 #define VEC_CFG 0x208 135 #define VEC_CFG_SG_MODE_MASK GENMASK(6, 5) 136 #define VEC_CFG_SG_MODE(x) ((x) << 5) 137 #define VEC_CFG_SG_EN BIT(4) 138 #define VEC_CFG_VEC_EN BIT(3) 139 #define VEC_CFG_MB_EN BIT(2) 140 #define VEC_CFG_ENABLE BIT(1) 141 #define VEC_CFG_TB_EN BIT(0) 142 143 #define VEC_DAC_TEST 0x20c 144 145 #define VEC_DAC_CONFIG 0x210 146 #define VEC_DAC_CONFIG_LDO_BIAS_CTRL(x) ((x) << 24) 147 #define VEC_DAC_CONFIG_DRIVER_CTRL(x) ((x) << 16) 148 #define VEC_DAC_CONFIG_DAC_CTRL(x) (x) 149 150 #define VEC_DAC_MISC 0x214 151 #define VEC_DAC_MISC_VCD_CTRL_MASK GENMASK(31, 16) 152 #define VEC_DAC_MISC_VCD_CTRL(x) ((x) << 16) 153 #define VEC_DAC_MISC_VID_ACT BIT(8) 154 #define VEC_DAC_MISC_VCD_PWRDN BIT(6) 155 #define VEC_DAC_MISC_BIAS_PWRDN BIT(5) 156 #define VEC_DAC_MISC_DAC_PWRDN BIT(2) 157 #define VEC_DAC_MISC_LDO_PWRDN BIT(1) 158 #define VEC_DAC_MISC_DAC_RST_N BIT(0) 159 160 161 /* General VEC hardware state. */ 162 struct vc4_vec { 163 struct platform_device *pdev; 164 165 struct drm_encoder *encoder; 166 struct drm_connector *connector; 167 168 void __iomem *regs; 169 170 struct clk *clock; 171 172 const struct vc4_vec_tv_mode *tv_mode; 173 }; 174 175 #define VEC_READ(offset) readl(vec->regs + (offset)) 176 #define VEC_WRITE(offset, val) writel(val, vec->regs + (offset)) 177 178 /* VC4 VEC encoder KMS struct */ 179 struct vc4_vec_encoder { 180 struct vc4_encoder base; 181 struct vc4_vec *vec; 182 }; 183 184 static inline struct vc4_vec_encoder * 185 to_vc4_vec_encoder(struct drm_encoder *encoder) 186 { 187 return container_of(encoder, struct vc4_vec_encoder, base.base); 188 } 189 190 /* VC4 VEC connector KMS struct */ 191 struct vc4_vec_connector { 192 struct drm_connector base; 193 struct vc4_vec *vec; 194 195 /* Since the connector is attached to just the one encoder, 196 * this is the reference to it so we can do the best_encoder() 197 * hook. 198 */ 199 struct drm_encoder *encoder; 200 }; 201 202 static inline struct vc4_vec_connector * 203 to_vc4_vec_connector(struct drm_connector *connector) 204 { 205 return container_of(connector, struct vc4_vec_connector, base); 206 } 207 208 enum vc4_vec_tv_mode_id { 209 VC4_VEC_TV_MODE_NTSC, 210 VC4_VEC_TV_MODE_NTSC_J, 211 VC4_VEC_TV_MODE_PAL, 212 VC4_VEC_TV_MODE_PAL_M, 213 }; 214 215 struct vc4_vec_tv_mode { 216 const struct drm_display_mode *mode; 217 void (*mode_set)(struct vc4_vec *vec); 218 }; 219 220 #define VEC_REG(reg) { reg, #reg } 221 static const struct { 222 u32 reg; 223 const char *name; 224 } vec_regs[] = { 225 VEC_REG(VEC_WSE_CONTROL), 226 VEC_REG(VEC_WSE_WSS_DATA), 227 VEC_REG(VEC_WSE_VPS_DATA1), 228 VEC_REG(VEC_WSE_VPS_CONTROL), 229 VEC_REG(VEC_REVID), 230 VEC_REG(VEC_CONFIG0), 231 VEC_REG(VEC_SCHPH), 232 VEC_REG(VEC_CLMP0_START), 233 VEC_REG(VEC_CLMP0_END), 234 VEC_REG(VEC_FREQ3_2), 235 VEC_REG(VEC_FREQ1_0), 236 VEC_REG(VEC_CONFIG1), 237 VEC_REG(VEC_CONFIG2), 238 VEC_REG(VEC_INTERRUPT_CONTROL), 239 VEC_REG(VEC_INTERRUPT_STATUS), 240 VEC_REG(VEC_FCW_SECAM_B), 241 VEC_REG(VEC_SECAM_GAIN_VAL), 242 VEC_REG(VEC_CONFIG3), 243 VEC_REG(VEC_STATUS0), 244 VEC_REG(VEC_MASK0), 245 VEC_REG(VEC_CFG), 246 VEC_REG(VEC_DAC_TEST), 247 VEC_REG(VEC_DAC_CONFIG), 248 VEC_REG(VEC_DAC_MISC), 249 }; 250 251 #ifdef CONFIG_DEBUG_FS 252 int vc4_vec_debugfs_regs(struct seq_file *m, void *unused) 253 { 254 struct drm_info_node *node = (struct drm_info_node *)m->private; 255 struct drm_device *dev = node->minor->dev; 256 struct vc4_dev *vc4 = to_vc4_dev(dev); 257 struct vc4_vec *vec = vc4->vec; 258 int i; 259 260 if (!vec) 261 return 0; 262 263 for (i = 0; i < ARRAY_SIZE(vec_regs); i++) { 264 seq_printf(m, "%s (0x%04x): 0x%08x\n", 265 vec_regs[i].name, vec_regs[i].reg, 266 VEC_READ(vec_regs[i].reg)); 267 } 268 269 return 0; 270 } 271 #endif 272 273 static void vc4_vec_ntsc_mode_set(struct vc4_vec *vec) 274 { 275 VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN); 276 VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); 277 } 278 279 static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec) 280 { 281 VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD); 282 VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); 283 } 284 285 static const struct drm_display_mode ntsc_mode = { 286 DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500, 287 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0, 288 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0, 289 DRM_MODE_FLAG_INTERLACE) 290 }; 291 292 static void vc4_vec_pal_mode_set(struct vc4_vec *vec) 293 { 294 VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); 295 VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); 296 } 297 298 static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec) 299 { 300 VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); 301 VEC_WRITE(VEC_CONFIG1, 302 VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ); 303 VEC_WRITE(VEC_FREQ3_2, 0x223b); 304 VEC_WRITE(VEC_FREQ1_0, 0x61d1); 305 } 306 307 static const struct drm_display_mode pal_mode = { 308 DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500, 309 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0, 310 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0, 311 DRM_MODE_FLAG_INTERLACE) 312 }; 313 314 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = { 315 [VC4_VEC_TV_MODE_NTSC] = { 316 .mode = &ntsc_mode, 317 .mode_set = vc4_vec_ntsc_mode_set, 318 }, 319 [VC4_VEC_TV_MODE_NTSC_J] = { 320 .mode = &ntsc_mode, 321 .mode_set = vc4_vec_ntsc_j_mode_set, 322 }, 323 [VC4_VEC_TV_MODE_PAL] = { 324 .mode = &pal_mode, 325 .mode_set = vc4_vec_pal_mode_set, 326 }, 327 [VC4_VEC_TV_MODE_PAL_M] = { 328 .mode = &pal_mode, 329 .mode_set = vc4_vec_pal_m_mode_set, 330 }, 331 }; 332 333 static enum drm_connector_status 334 vc4_vec_connector_detect(struct drm_connector *connector, bool force) 335 { 336 return connector_status_unknown; 337 } 338 339 static void vc4_vec_connector_destroy(struct drm_connector *connector) 340 { 341 drm_connector_unregister(connector); 342 drm_connector_cleanup(connector); 343 } 344 345 static int vc4_vec_connector_get_modes(struct drm_connector *connector) 346 { 347 struct drm_connector_state *state = connector->state; 348 struct drm_display_mode *mode; 349 350 mode = drm_mode_duplicate(connector->dev, 351 vc4_vec_tv_modes[state->tv.mode].mode); 352 if (!mode) { 353 DRM_ERROR("Failed to create a new display mode\n"); 354 return -ENOMEM; 355 } 356 357 drm_mode_probed_add(connector, mode); 358 359 return 1; 360 } 361 362 static const struct drm_connector_funcs vc4_vec_connector_funcs = { 363 .dpms = drm_atomic_helper_connector_dpms, 364 .detect = vc4_vec_connector_detect, 365 .fill_modes = drm_helper_probe_single_connector_modes, 366 .set_property = drm_atomic_helper_connector_set_property, 367 .destroy = vc4_vec_connector_destroy, 368 .reset = drm_atomic_helper_connector_reset, 369 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 370 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 371 }; 372 373 static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = { 374 .get_modes = vc4_vec_connector_get_modes, 375 }; 376 377 static struct drm_connector *vc4_vec_connector_init(struct drm_device *dev, 378 struct vc4_vec *vec) 379 { 380 struct drm_connector *connector = NULL; 381 struct vc4_vec_connector *vec_connector; 382 383 vec_connector = devm_kzalloc(dev->dev, sizeof(*vec_connector), 384 GFP_KERNEL); 385 if (!vec_connector) 386 return ERR_PTR(-ENOMEM); 387 388 connector = &vec_connector->base; 389 connector->interlace_allowed = true; 390 391 vec_connector->encoder = vec->encoder; 392 vec_connector->vec = vec; 393 394 drm_connector_init(dev, connector, &vc4_vec_connector_funcs, 395 DRM_MODE_CONNECTOR_Composite); 396 drm_connector_helper_add(connector, &vc4_vec_connector_helper_funcs); 397 398 drm_object_attach_property(&connector->base, 399 dev->mode_config.tv_mode_property, 400 VC4_VEC_TV_MODE_NTSC); 401 vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC]; 402 403 drm_mode_connector_attach_encoder(connector, vec->encoder); 404 405 return connector; 406 } 407 408 static const struct drm_encoder_funcs vc4_vec_encoder_funcs = { 409 .destroy = drm_encoder_cleanup, 410 }; 411 412 static void vc4_vec_encoder_disable(struct drm_encoder *encoder) 413 { 414 struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder); 415 struct vc4_vec *vec = vc4_vec_encoder->vec; 416 int ret; 417 418 VEC_WRITE(VEC_CFG, 0); 419 VEC_WRITE(VEC_DAC_MISC, 420 VEC_DAC_MISC_VCD_PWRDN | 421 VEC_DAC_MISC_BIAS_PWRDN | 422 VEC_DAC_MISC_DAC_PWRDN | 423 VEC_DAC_MISC_LDO_PWRDN); 424 425 clk_disable_unprepare(vec->clock); 426 427 ret = pm_runtime_put(&vec->pdev->dev); 428 if (ret < 0) { 429 DRM_ERROR("Failed to release power domain: %d\n", ret); 430 return; 431 } 432 } 433 434 static void vc4_vec_encoder_enable(struct drm_encoder *encoder) 435 { 436 struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder); 437 struct vc4_vec *vec = vc4_vec_encoder->vec; 438 int ret; 439 440 ret = pm_runtime_get_sync(&vec->pdev->dev); 441 if (ret < 0) { 442 DRM_ERROR("Failed to retain power domain: %d\n", ret); 443 return; 444 } 445 446 /* 447 * We need to set the clock rate each time we enable the encoder 448 * because there's a chance we share the same parent with the HDMI 449 * clock, and both drivers are requesting different rates. 450 * The good news is, these 2 encoders cannot be enabled at the same 451 * time, thus preventing incompatible rate requests. 452 */ 453 ret = clk_set_rate(vec->clock, 108000000); 454 if (ret) { 455 DRM_ERROR("Failed to set clock rate: %d\n", ret); 456 return; 457 } 458 459 ret = clk_prepare_enable(vec->clock); 460 if (ret) { 461 DRM_ERROR("Failed to turn on core clock: %d\n", ret); 462 return; 463 } 464 465 /* Reset the different blocks */ 466 VEC_WRITE(VEC_WSE_RESET, 1); 467 VEC_WRITE(VEC_SOFT_RESET, 1); 468 469 /* Disable the CGSM-A and WSE blocks */ 470 VEC_WRITE(VEC_WSE_CONTROL, 0); 471 472 /* Write config common to all modes. */ 473 474 /* 475 * Color subcarrier phase: phase = 360 * SCHPH / 256. 476 * 0x28 <=> 39.375 deg. 477 */ 478 VEC_WRITE(VEC_SCHPH, 0x28); 479 480 /* 481 * Reset to default values. 482 */ 483 VEC_WRITE(VEC_CLMP0_START, 0xac); 484 VEC_WRITE(VEC_CLMP0_END, 0xec); 485 VEC_WRITE(VEC_CONFIG2, 486 VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS); 487 VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD); 488 VEC_WRITE(VEC_DAC_CONFIG, 489 VEC_DAC_CONFIG_DAC_CTRL(0xc) | 490 VEC_DAC_CONFIG_DRIVER_CTRL(0xc) | 491 VEC_DAC_CONFIG_LDO_BIAS_CTRL(0x46)); 492 493 /* Mask all interrupts. */ 494 VEC_WRITE(VEC_MASK0, 0); 495 496 vec->tv_mode->mode_set(vec); 497 498 VEC_WRITE(VEC_DAC_MISC, 499 VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N); 500 VEC_WRITE(VEC_CFG, VEC_CFG_VEC_EN); 501 } 502 503 504 static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder, 505 const struct drm_display_mode *mode, 506 struct drm_display_mode *adjusted_mode) 507 { 508 return true; 509 } 510 511 static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder, 512 struct drm_crtc_state *crtc_state, 513 struct drm_connector_state *conn_state) 514 { 515 struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder); 516 struct vc4_vec *vec = vc4_vec_encoder->vec; 517 518 vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode]; 519 } 520 521 static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, 522 struct drm_crtc_state *crtc_state, 523 struct drm_connector_state *conn_state) 524 { 525 const struct vc4_vec_tv_mode *vec_mode; 526 527 vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode]; 528 529 if (conn_state->crtc && 530 !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode)) 531 return -EINVAL; 532 533 return 0; 534 } 535 536 static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = { 537 .disable = vc4_vec_encoder_disable, 538 .enable = vc4_vec_encoder_enable, 539 .mode_fixup = vc4_vec_encoder_mode_fixup, 540 .atomic_check = vc4_vec_encoder_atomic_check, 541 .atomic_mode_set = vc4_vec_encoder_atomic_mode_set, 542 }; 543 544 static const struct of_device_id vc4_vec_dt_match[] = { 545 { .compatible = "brcm,bcm2835-vec", .data = NULL }, 546 { /* sentinel */ }, 547 }; 548 549 static const char * const tv_mode_names[] = { 550 [VC4_VEC_TV_MODE_NTSC] = "NTSC", 551 [VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J", 552 [VC4_VEC_TV_MODE_PAL] = "PAL", 553 [VC4_VEC_TV_MODE_PAL_M] = "PAL-M", 554 }; 555 556 static int vc4_vec_bind(struct device *dev, struct device *master, void *data) 557 { 558 struct platform_device *pdev = to_platform_device(dev); 559 struct drm_device *drm = dev_get_drvdata(master); 560 struct vc4_dev *vc4 = to_vc4_dev(drm); 561 struct vc4_vec *vec; 562 struct vc4_vec_encoder *vc4_vec_encoder; 563 int ret; 564 565 ret = drm_mode_create_tv_properties(drm, ARRAY_SIZE(tv_mode_names), 566 tv_mode_names); 567 if (ret) 568 return ret; 569 570 vec = devm_kzalloc(dev, sizeof(*vec), GFP_KERNEL); 571 if (!vec) 572 return -ENOMEM; 573 574 vc4_vec_encoder = devm_kzalloc(dev, sizeof(*vc4_vec_encoder), 575 GFP_KERNEL); 576 if (!vc4_vec_encoder) 577 return -ENOMEM; 578 vc4_vec_encoder->base.type = VC4_ENCODER_TYPE_VEC; 579 vc4_vec_encoder->vec = vec; 580 vec->encoder = &vc4_vec_encoder->base.base; 581 582 vec->pdev = pdev; 583 vec->regs = vc4_ioremap_regs(pdev, 0); 584 if (IS_ERR(vec->regs)) 585 return PTR_ERR(vec->regs); 586 587 vec->clock = devm_clk_get(dev, NULL); 588 if (IS_ERR(vec->clock)) { 589 ret = PTR_ERR(vec->clock); 590 if (ret != -EPROBE_DEFER) 591 DRM_ERROR("Failed to get clock: %d\n", ret); 592 return ret; 593 } 594 595 pm_runtime_enable(dev); 596 597 drm_encoder_init(drm, vec->encoder, &vc4_vec_encoder_funcs, 598 DRM_MODE_ENCODER_TVDAC, NULL); 599 drm_encoder_helper_add(vec->encoder, &vc4_vec_encoder_helper_funcs); 600 601 vec->connector = vc4_vec_connector_init(drm, vec); 602 if (IS_ERR(vec->connector)) { 603 ret = PTR_ERR(vec->connector); 604 goto err_destroy_encoder; 605 } 606 607 dev_set_drvdata(dev, vec); 608 609 vc4->vec = vec; 610 611 return 0; 612 613 err_destroy_encoder: 614 drm_encoder_cleanup(vec->encoder); 615 pm_runtime_disable(dev); 616 617 return ret; 618 } 619 620 static void vc4_vec_unbind(struct device *dev, struct device *master, 621 void *data) 622 { 623 struct drm_device *drm = dev_get_drvdata(master); 624 struct vc4_dev *vc4 = to_vc4_dev(drm); 625 struct vc4_vec *vec = dev_get_drvdata(dev); 626 627 vc4_vec_connector_destroy(vec->connector); 628 drm_encoder_cleanup(vec->encoder); 629 pm_runtime_disable(dev); 630 631 vc4->vec = NULL; 632 } 633 634 static const struct component_ops vc4_vec_ops = { 635 .bind = vc4_vec_bind, 636 .unbind = vc4_vec_unbind, 637 }; 638 639 static int vc4_vec_dev_probe(struct platform_device *pdev) 640 { 641 return component_add(&pdev->dev, &vc4_vec_ops); 642 } 643 644 static int vc4_vec_dev_remove(struct platform_device *pdev) 645 { 646 component_del(&pdev->dev, &vc4_vec_ops); 647 return 0; 648 } 649 650 struct platform_driver vc4_vec_driver = { 651 .probe = vc4_vec_dev_probe, 652 .remove = vc4_vec_dev_remove, 653 .driver = { 654 .name = "vc4_vec", 655 .of_match_table = vc4_vec_dt_match, 656 }, 657 }; 658