Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

Summary:
- Support for pipeline clock between KMS drivers.
. Exynos SoC is required to control clocks across KMS drivers
according to Exynos SoC version. So this patch refactos
some relevant codes and provides generic solution for it.
- Add Exynos5433 SoC support to HDMI parts - HDMI and DECON-TV.
- Add HW trigger mode support to CRTC drivers.
. In case of using i80 Panel, some Exynos SoC supports HW trigger
mode so this patch makes trigger mode - HW or SW trigger - to be
set according to SoC version properly.
- And some cleanups and regression fixups.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (39 commits)
drm/exynos: clean up register definions for fimd and decon
drm/exynos: decon: clean up interface type
drm/exynos: fimd: add HW trigger support
drm/exynos: clean up wait_for_vblank
drm/exynos: mixer: use generic of_device_get_match_data helper
drm/exynos: mixer: remove support for non-dt platforms
drm/exynos: hdmi: use generic of_device_get_match_data helper
drm/exynos: rotator: use generic of_device_get_match_data helper
drm/exynos: fimd: use generic of_device_get_match_data helper
drm/exynos: dsi: use generic of_device_get_match_data helper
drm/exynos: exynos5433_decon: use generic of_device_get_match_data helper
drm/exynos: convert clock_enable crtc callback to pipeline clock
drm/exynos/mixer: enable HDMI-PHY before configuring MIXER
drm/exynos/decon5433: enable HDMI-PHY before configuring DECON
drm/exynos: add support for pipeline clock to the framework
drm/exynos: add helper to get crtc from pipe
drm/exynos/decon5433: do not protect window in plane disable
drm/exynos/decon5433: reset decon on start
drm/exynos/decon5433: fix DECON standalone update
drm/exynos/hdmi: remove registry dump
...

+569 -620
+3 -2
Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
··· 5 5 buffer to an external LCD interface. 6 6 7 7 Required properties: 8 - - compatible: value should be "samsung,exynos5433-decon"; 8 + - compatible: value should be one of: 9 + "samsung,exynos5433-decon", "samsung,exynos5433-decon-tv"; 9 10 - reg: physical base address and length of the DECON registers set. 10 11 - interrupts: should contain a list of all DECON IP block interrupts in the 11 12 order: VSYNC, LCD_SYSTEM. The interrupt specifier format ··· 17 16 - clocks: must include clock specifiers corresponding to entries in the 18 17 clock-names property. 19 18 - clock-names: list of clock names sorted in the same order as the clocks 20 - property. Must contain "aclk_decon", "aclk_smmu_decon0x", 19 + property. Must contain "pclk", "aclk_decon", "aclk_smmu_decon0x", 21 20 "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk", 22 21 "sclk_decon_eclk" 23 22 - ports: contains a port which is connected to mic node. address-cells and
+24 -3
Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
··· 5 5 1) "samsung,exynos4210-hdmi" 6 6 2) "samsung,exynos4212-hdmi" 7 7 3) "samsung,exynos5420-hdmi" 8 + 4) "samsung,exynos5433-hdmi" 8 9 - reg: physical base address of the hdmi and length of memory mapped 9 10 region. 10 11 - interrupts: interrupt number to the cpu. ··· 13 12 a) phandle of the gpio controller node. 14 13 b) pin number within the gpio controller. 15 14 c) optional flags and pull up/down. 15 + - ddc: phandle to the hdmi ddc node 16 + - phy: phandle to the hdmi phy node 17 + - samsung,syscon-phandle: phandle for system controller node for PMU. 18 + 19 + Required properties for Exynos 4210, 4212, 5420 and 5433: 16 20 - clocks: list of clock IDs from SoC clock driver. 17 21 a) hdmi: Gate of HDMI IP bus clock. 18 22 b) sclk_hdmi: Gate of HDMI special clock. ··· 31 25 sclk_pixel. 32 26 - clock-names: aliases as per driver requirements for above clock IDs: 33 27 "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi". 34 - - ddc: phandle to the hdmi ddc node 35 - - phy: phandle to the hdmi phy node 36 - - samsung,syscon-phandle: phandle for system controller node for PMU. 28 + 29 + Required properties for Exynos 5433: 30 + - clocks: list of clock specifiers according to common clock bindings. 31 + a) hdmi_pclk: Gate of HDMI IP APB bus. 32 + b) hdmi_i_pclk: Gate of HDMI-PHY IP APB bus. 33 + d) i_tmds_clk: Gate of HDMI TMDS clock. 34 + e) i_pixel_clk: Gate of HDMI pixel clock. 35 + f) i_spdif_clk: Gate of HDMI SPDIF clock. 36 + g) oscclk: Oscillator clock, used as parent of following *_user clocks 37 + in case HDMI-PHY is not operational. 38 + h) tmds_clko: TMDS clock generated by HDMI-PHY. 39 + i) tmds_clko_user: MUX used to switch between oscclk and tmds_clko, 40 + respectively if HDMI-PHY is off and operational. 41 + j) pixel_clko: Pixel clock generated by HDMI-PHY. 42 + k) pixel_clko_user: MUX used to switch between oscclk and pixel_clko, 43 + respectively if HDMI-PHY is off and operational. 44 + - clock-names: aliases for above clock specfiers. 45 + - samsung,sysreg: handle to syscon used to control the system registers. 37 46 38 47 Example: 39 48
+1 -1
drivers/gpu/drm/exynos/Kconfig
··· 95 95 96 96 config DRM_EXYNOS_G2D 97 97 bool "G2D" 98 - depends on !VIDEO_SAMSUNG_S5P_G2D 98 + depends on VIDEO_SAMSUNG_S5P_G2D=n 99 99 select FRAME_VECTOR 100 100 help 101 101 Choose this option if you want to use Exynos G2D for DRM.
+3 -3
drivers/gpu/drm/exynos/Makefile
··· 2 2 # Makefile for the drm device driver. This driver provides support for the 3 3 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 4 4 5 - exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \ 6 - exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \ 7 - exynos_drm_plane.o 5 + exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \ 6 + exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o 8 7 8 + exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o 9 9 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o 10 10 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 11 11 exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o
+44 -42
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
··· 28 28 #define WINDOWS_NR 3 29 29 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 30 30 31 + #define IFTYPE_I80 (1 << 0) 32 + #define I80_HW_TRG (1 << 1) 33 + #define IFTYPE_HDMI (1 << 2) 34 + 31 35 static const char * const decon_clks_name[] = { 32 36 "pclk", 33 37 "aclk_decon", ··· 40 36 "pclk_smmu_decon0x", 41 37 "sclk_decon_vclk", 42 38 "sclk_decon_eclk", 43 - }; 44 - 45 - enum decon_iftype { 46 - IFTYPE_RGB, 47 - IFTYPE_I80, 48 - IFTYPE_HDMI 49 39 }; 50 40 51 41 enum decon_flag_bits { ··· 59 61 struct clk *clks[ARRAY_SIZE(decon_clks_name)]; 60 62 int pipe; 61 63 unsigned long flags; 62 - enum decon_iftype out_type; 64 + unsigned long out_type; 63 65 int first_win; 64 66 }; 65 67 ··· 93 95 94 96 if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) { 95 97 val = VIDINTCON0_INTEN; 96 - if (ctx->out_type == IFTYPE_I80) 98 + if (ctx->out_type & IFTYPE_I80) 97 99 val |= VIDINTCON0_FRAMEDONE; 98 100 else 99 101 val |= VIDINTCON0_INTFRMEN; ··· 117 119 118 120 static void decon_setup_trigger(struct decon_context *ctx) 119 121 { 120 - u32 val = (ctx->out_type != IFTYPE_HDMI) 122 + u32 val = !(ctx->out_type & I80_HW_TRG) 121 123 ? TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | 122 124 TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN 123 125 : TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | 124 - TRIGCON_HWTRIGMASK_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB; 126 + TRIGCON_HWTRIGMASK | TRIGCON_HWTRIGEN; 125 127 writel(val, ctx->addr + DECON_TRIGCON); 126 128 } 127 129 ··· 134 136 if (test_bit(BIT_SUSPENDED, &ctx->flags)) 135 137 return; 136 138 137 - if (ctx->out_type == IFTYPE_HDMI) { 139 + if (ctx->out_type & IFTYPE_HDMI) { 138 140 m->crtc_hsync_start = m->crtc_hdisplay + 10; 139 141 m->crtc_hsync_end = m->crtc_htotal - 92; 140 142 m->crtc_vsync_start = m->crtc_vdisplay + 1; ··· 149 151 150 152 /* lcd on and use command if */ 151 153 val = VIDOUT_LCD_ON; 152 - if (ctx->out_type == IFTYPE_I80) 154 + if (ctx->out_type & IFTYPE_I80) { 153 155 val |= VIDOUT_COMMAND_IF; 154 - else 156 + decon_setup_trigger(ctx); 157 + } else { 155 158 val |= VIDOUT_RGB_IF; 159 + } 160 + 156 161 writel(val, ctx->addr + DECON_VIDOUTCON0); 157 162 158 163 val = VIDTCON2_LINEVAL(m->vdisplay - 1) | 159 164 VIDTCON2_HOZVAL(m->hdisplay - 1); 160 165 writel(val, ctx->addr + DECON_VIDTCON2); 161 166 162 - if (ctx->out_type != IFTYPE_I80) { 167 + if (!(ctx->out_type & IFTYPE_I80)) { 163 168 val = VIDTCON00_VBPD_F( 164 169 m->crtc_vtotal - m->crtc_vsync_end - 1) | 165 170 VIDTCON00_VFPD_F( ··· 184 183 writel(val, ctx->addr + DECON_VIDTCON11); 185 184 } 186 185 187 - decon_setup_trigger(ctx); 188 - 189 186 /* enable output and display signal */ 190 187 decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0); 188 + 189 + decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 191 190 } 192 191 193 192 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, ··· 301 300 val = dma_addr + pitch * state->src.h; 302 301 writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); 303 302 304 - if (ctx->out_type != IFTYPE_HDMI) 303 + if (!(ctx->out_type & IFTYPE_HDMI)) 305 304 val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14) 306 305 | BIT_VAL(state->crtc.w * bpp, 13, 0); 307 306 else ··· 313 312 314 313 /* window enable */ 315 314 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0); 316 - 317 - /* standalone update */ 318 - decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 319 315 } 320 316 321 317 static void decon_disable_plane(struct exynos_drm_crtc *crtc, ··· 324 326 if (test_bit(BIT_SUSPENDED, &ctx->flags)) 325 327 return; 326 328 327 - decon_shadow_protect_win(ctx, win, true); 328 - 329 - /* window disable */ 330 329 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); 331 - 332 - decon_shadow_protect_win(ctx, win, false); 333 - 334 - /* standalone update */ 335 - decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 336 330 } 337 331 338 332 static void decon_atomic_flush(struct exynos_drm_crtc *crtc) ··· 338 348 for (i = ctx->first_win; i < WINDOWS_NR; i++) 339 349 decon_shadow_protect_win(ctx, i, false); 340 350 341 - if (ctx->out_type == IFTYPE_I80) 351 + /* standalone update */ 352 + decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 353 + 354 + if (ctx->out_type & IFTYPE_I80) 342 355 set_bit(BIT_WIN_UPDATED, &ctx->flags); 343 356 } 344 357 ··· 367 374 368 375 WARN(tries == 0, "failed to software reset DECON\n"); 369 376 370 - if (ctx->out_type != IFTYPE_HDMI) 377 + if (!(ctx->out_type & IFTYPE_HDMI)) 371 378 return; 372 379 373 380 writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0); ··· 376 383 writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1); 377 384 writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN, 378 385 ctx->addr + DECON_CRCCTRL); 379 - decon_setup_trigger(ctx); 386 + 387 + if (ctx->out_type & IFTYPE_I80) 388 + decon_setup_trigger(ctx); 380 389 } 381 390 382 391 static void decon_enable(struct exynos_drm_crtc *crtc) ··· 390 395 391 396 pm_runtime_get_sync(ctx->dev); 392 397 398 + exynos_drm_pipe_clk_enable(crtc, true); 399 + 393 400 set_bit(BIT_CLKS_ENABLED, &ctx->flags); 401 + 402 + decon_swreset(ctx); 394 403 395 404 /* if vblank was enabled status, enable it again. */ 396 405 if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags)) ··· 422 423 decon_swreset(ctx); 423 424 424 425 clear_bit(BIT_CLKS_ENABLED, &ctx->flags); 426 + 427 + exynos_drm_pipe_clk_enable(crtc, false); 425 428 426 429 pm_runtime_put_sync(ctx->dev); 427 430 ··· 460 459 decon_shadow_protect_win(ctx, win, true); 461 460 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); 462 461 decon_shadow_protect_win(ctx, win, false); 463 - decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 464 462 } 463 + 464 + decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 465 + 465 466 /* TODO: wait for possible vsync */ 466 467 msleep(50); 467 468 ··· 512 509 } 513 510 514 511 exynos_plane = &ctx->planes[ctx->first_win]; 515 - out_type = (ctx->out_type == IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI 512 + out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI 516 513 : EXYNOS_DISPLAY_TYPE_LCD; 517 514 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, 518 515 ctx->pipe, out_type, ··· 620 617 static const struct of_device_id exynos5433_decon_driver_dt_match[] = { 621 618 { 622 619 .compatible = "samsung,exynos5433-decon", 623 - .data = (void *)IFTYPE_RGB 620 + .data = (void *)I80_HW_TRG 624 621 }, 625 622 { 626 623 .compatible = "samsung,exynos5433-decon-tv", 627 - .data = (void *)IFTYPE_HDMI 624 + .data = (void *)(I80_HW_TRG | IFTYPE_HDMI) 628 625 }, 629 626 {}, 630 627 }; ··· 632 629 633 630 static int exynos5433_decon_probe(struct platform_device *pdev) 634 631 { 635 - const struct of_device_id *of_id; 636 632 struct device *dev = &pdev->dev; 637 633 struct decon_context *ctx; 638 634 struct resource *res; ··· 644 642 645 643 __set_bit(BIT_SUSPENDED, &ctx->flags); 646 644 ctx->dev = dev; 645 + ctx->out_type = (unsigned long)of_device_get_match_data(dev); 647 646 648 - of_id = of_match_device(exynos5433_decon_driver_dt_match, &pdev->dev); 649 - ctx->out_type = (enum decon_iftype)of_id->data; 650 - 651 - if (ctx->out_type == IFTYPE_HDMI) 647 + if (ctx->out_type & IFTYPE_HDMI) { 652 648 ctx->first_win = 1; 653 - else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) 654 649 ctx->out_type = IFTYPE_I80; 650 + } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) { 651 + ctx->out_type = IFTYPE_I80; 652 + } 655 653 656 654 for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 657 655 struct clk *clk; ··· 676 674 } 677 675 678 676 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 679 - (ctx->out_type == IFTYPE_I80) ? "lcd_sys" : "vsync"); 677 + (ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync"); 680 678 if (!res) { 681 679 dev_err(dev, "cannot find IRQ resource\n"); 682 680 return -ENXIO;
-1
drivers/gpu/drm/exynos/exynos7_drm_decon.c
··· 593 593 .commit = decon_commit, 594 594 .enable_vblank = decon_enable_vblank, 595 595 .disable_vblank = decon_disable_vblank, 596 - .wait_for_vblank = decon_wait_for_vblank, 597 596 .atomic_begin = decon_atomic_begin, 598 597 .update_plane = decon_update_plane, 599 598 .disable_plane = decon_disable_plane,
+3 -6
drivers/gpu/drm/exynos/exynos_dp.c
··· 48 48 { 49 49 struct exynos_dp_device *dp = to_dp(plat_data); 50 50 struct drm_encoder *encoder = &dp->encoder; 51 - struct exynos_drm_crtc *crtc; 52 51 53 - if (!encoder) 54 - return -1; 52 + if (!encoder->crtc) 53 + return -EPERM; 55 54 56 - crtc = to_exynos_crtc(encoder->crtc); 57 - if (crtc && crtc->ops && crtc->ops->clock_enable) 58 - crtc->ops->clock_enable(crtc, enable); 55 + exynos_drm_pipe_clk_enable(to_exynos_crtc(encoder->crtc), enable); 59 56 60 57 return 0; 61 58 }
+1 -1
drivers/gpu/drm/exynos/exynos_drm_core.c
··· 101 101 return 0; 102 102 103 103 err: 104 - list_for_each_entry_reverse(subdrv, &subdrv->list, list) { 104 + list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) { 105 105 if (subdrv->close) 106 106 subdrv->close(dev, subdrv->dev, file); 107 107 }
+4 -6
drivers/gpu/drm/exynos/exynos_drm_crtc.c
··· 157 157 158 158 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) 159 159 { 160 - struct exynos_drm_private *private = dev->dev_private; 161 - struct exynos_drm_crtc *exynos_crtc = 162 - to_exynos_crtc(private->crtc[pipe]); 160 + struct exynos_drm_crtc *exynos_crtc = exynos_drm_crtc_from_pipe(dev, 161 + pipe); 163 162 164 163 if (exynos_crtc->ops->enable_vblank) 165 164 return exynos_crtc->ops->enable_vblank(exynos_crtc); ··· 168 169 169 170 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe) 170 171 { 171 - struct exynos_drm_private *private = dev->dev_private; 172 - struct exynos_drm_crtc *exynos_crtc = 173 - to_exynos_crtc(private->crtc[pipe]); 172 + struct exynos_drm_crtc *exynos_crtc = exynos_drm_crtc_from_pipe(dev, 173 + pipe); 174 174 175 175 if (exynos_crtc->ops->disable_vblank) 176 176 exynos_crtc->ops->disable_vblank(exynos_crtc);
+20 -8
drivers/gpu/drm/exynos/exynos_drm_drv.h
··· 120 120 * @commit: set current hw specific display mode to hw. 121 121 * @enable_vblank: specific driver callback for enabling vblank interrupt. 122 122 * @disable_vblank: specific driver callback for disabling vblank interrupt. 123 - * @wait_for_vblank: wait for vblank interrupt to make sure that 124 - * hardware overlay is updated. 125 123 * @atomic_check: validate state 126 124 * @atomic_begin: prepare device to receive an update 127 125 * @atomic_flush: mark the end of device update ··· 127 129 * @disable_plane: disable hardware specific overlay. 128 130 * @te_handler: trigger to transfer video image at the tearing effect 129 131 * synchronization signal if there is a page flip request. 130 - * @clock_enable: optional function enabling/disabling display domain clock, 131 - * called from exynos-dp driver before powering up (with 132 - * 'enable' argument as true) and after powering down (with 133 - * 'enable' as false). 134 132 */ 135 133 struct exynos_drm_crtc; 136 134 struct exynos_drm_crtc_ops { ··· 135 141 void (*commit)(struct exynos_drm_crtc *crtc); 136 142 int (*enable_vblank)(struct exynos_drm_crtc *crtc); 137 143 void (*disable_vblank)(struct exynos_drm_crtc *crtc); 138 - void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); 139 144 int (*atomic_check)(struct exynos_drm_crtc *crtc, 140 145 struct drm_crtc_state *state); 141 146 void (*atomic_begin)(struct exynos_drm_crtc *crtc); ··· 144 151 struct exynos_drm_plane *plane); 145 152 void (*atomic_flush)(struct exynos_drm_crtc *crtc); 146 153 void (*te_handler)(struct exynos_drm_crtc *crtc); 147 - void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); 154 + }; 155 + 156 + struct exynos_drm_clk { 157 + void (*enable)(struct exynos_drm_clk *clk, bool enable); 148 158 }; 149 159 150 160 /* ··· 178 182 atomic_t pending_update; 179 183 const struct exynos_drm_crtc_ops *ops; 180 184 void *ctx; 185 + struct exynos_drm_clk *pipe_clk; 181 186 }; 187 + 188 + static inline void exynos_drm_pipe_clk_enable(struct exynos_drm_crtc *crtc, 189 + bool enable) 190 + { 191 + if (crtc->pipe_clk) 192 + crtc->pipe_clk->enable(crtc->pipe_clk, enable); 193 + } 182 194 183 195 struct exynos_drm_g2d_private { 184 196 struct device *dev; ··· 235 231 spinlock_t lock; 236 232 wait_queue_head_t wait; 237 233 }; 234 + 235 + static inline struct exynos_drm_crtc * 236 + exynos_drm_crtc_from_pipe(struct drm_device *dev, int pipe) 237 + { 238 + struct exynos_drm_private *private = dev->dev_private; 239 + 240 + return to_exynos_crtc(private->crtc[pipe]); 241 + } 238 242 239 243 static inline struct device *to_dma_dev(struct drm_device *dev) 240 244 {
+9 -18
drivers/gpu/drm/exynos/exynos_drm_dsi.c
··· 280 280 spinlock_t transfer_lock; /* protects transfer_list */ 281 281 struct list_head transfer_list; 282 282 283 - struct exynos_dsi_driver_data *driver_data; 283 + const struct exynos_dsi_driver_data *driver_data; 284 284 struct device_node *bridge_node; 285 285 }; 286 286 ··· 532 532 { } 533 533 }; 534 534 535 - static inline struct exynos_dsi_driver_data *exynos_dsi_get_driver_data( 536 - struct platform_device *pdev) 537 - { 538 - const struct of_device_id *of_id = 539 - of_match_device(exynos_dsi_of_match, &pdev->dev); 540 - 541 - return (struct exynos_dsi_driver_data *)of_id->data; 542 - } 543 - 544 535 static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi) 545 536 { 546 537 if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300))) ··· 555 564 static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi, 556 565 unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s) 557 566 { 558 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 567 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 559 568 unsigned long best_freq = 0; 560 569 u32 min_delta = 0xffffffff; 561 570 u8 p_min, p_max; ··· 609 618 static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi, 610 619 unsigned long freq) 611 620 { 612 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 621 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 613 622 unsigned long fin, fout; 614 623 int timeout; 615 624 u8 p, s; ··· 703 712 704 713 static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) 705 714 { 706 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 715 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 707 716 const unsigned int *reg_values = driver_data->reg_values; 708 717 u32 reg; 709 718 ··· 781 790 782 791 static int exynos_dsi_init_link(struct exynos_dsi *dsi) 783 792 { 784 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 793 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 785 794 int timeout; 786 795 u32 reg; 787 796 u32 lanes_mask; ··· 1325 1334 1326 1335 static int exynos_dsi_init(struct exynos_dsi *dsi) 1327 1336 { 1328 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1337 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1329 1338 1330 1339 exynos_dsi_reset(dsi); 1331 1340 exynos_dsi_enable_irq(dsi); ··· 1824 1833 dsi->dsi_host.dev = dev; 1825 1834 1826 1835 dsi->dev = dev; 1827 - dsi->driver_data = exynos_dsi_get_driver_data(pdev); 1836 + dsi->driver_data = of_device_get_match_data(dev); 1828 1837 1829 1838 ret = exynos_dsi_parse_dt(dsi); 1830 1839 if (ret) ··· 1908 1917 { 1909 1918 struct drm_encoder *encoder = dev_get_drvdata(dev); 1910 1919 struct exynos_dsi *dsi = encoder_to_dsi(encoder); 1911 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1920 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1912 1921 int ret, i; 1913 1922 1914 1923 usleep_range(10000, 20000); ··· 1939 1948 { 1940 1949 struct drm_encoder *encoder = dev_get_drvdata(dev); 1941 1950 struct exynos_dsi *dsi = encoder_to_dsi(encoder); 1942 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1951 + const struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1943 1952 int ret, i; 1944 1953 1945 1954 ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
-11
drivers/gpu/drm/exynos/exynos_drm_fb.c
··· 199 199 return exynos_fb->dma_addr[index]; 200 200 } 201 201 202 - static void exynos_drm_output_poll_changed(struct drm_device *dev) 203 - { 204 - struct exynos_drm_private *private = dev->dev_private; 205 - struct drm_fb_helper *fb_helper = private->fb_helper; 206 - 207 - if (fb_helper) 208 - drm_fb_helper_hotplug_event(fb_helper); 209 - else 210 - exynos_drm_fbdev_init(dev); 211 - } 212 - 213 202 static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { 214 203 .fb_create = exynos_user_fb_create, 215 204 .output_poll_changed = exynos_drm_output_poll_changed,
+11
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
··· 311 311 312 312 drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper); 313 313 } 314 + 315 + void exynos_drm_output_poll_changed(struct drm_device *dev) 316 + { 317 + struct exynos_drm_private *private = dev->dev_private; 318 + struct drm_fb_helper *fb_helper = private->fb_helper; 319 + 320 + if (fb_helper) 321 + drm_fb_helper_hotplug_event(fb_helper); 322 + else 323 + exynos_drm_fbdev_init(dev); 324 + }
+22 -1
drivers/gpu/drm/exynos/exynos_drm_fbdev.h
··· 15 15 #ifndef _EXYNOS_DRM_FBDEV_H_ 16 16 #define _EXYNOS_DRM_FBDEV_H_ 17 17 18 + #ifdef CONFIG_DRM_FBDEV_EMULATION 19 + 18 20 int exynos_drm_fbdev_init(struct drm_device *dev); 19 - int exynos_drm_fbdev_reinit(struct drm_device *dev); 20 21 void exynos_drm_fbdev_fini(struct drm_device *dev); 21 22 void exynos_drm_fbdev_restore_mode(struct drm_device *dev); 23 + void exynos_drm_output_poll_changed(struct drm_device *dev); 24 + 25 + #else 26 + 27 + static inline int exynos_drm_fbdev_init(struct drm_device *dev) 28 + { 29 + return 0; 30 + } 31 + 32 + static inline void exynos_drm_fbdev_fini(struct drm_device *dev) 33 + { 34 + } 35 + 36 + static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev) 37 + { 38 + } 39 + 40 + #define exynos_drm_output_poll_changed (NULL) 41 + 42 + #endif 22 43 23 44 #endif
+67 -32
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 68 68 /* color key value register for hardware window 1 ~ 4. */ 69 69 #define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8)) 70 70 71 - /* I80 / RGB trigger control register */ 71 + /* I80 trigger control register */ 72 72 #define TRIGCON 0x1A4 73 - #define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0) 74 - #define SWTRGCMD_I80_RGB_ENABLE (1 << 1) 73 + #define TRGMODE_ENABLE (1 << 0) 74 + #define SWTRGCMD_ENABLE (1 << 1) 75 + /* Exynos3250, 3472, 4415, 5260 5410, 5420 and 5422 only supported. */ 76 + #define HWTRGEN_ENABLE (1 << 3) 77 + #define HWTRGMASK_ENABLE (1 << 4) 78 + /* Exynos3250, 3472, 4415, 5260, 5420 and 5422 only supported. */ 79 + #define HWTRIGEN_PER_ENABLE (1 << 31) 75 80 76 81 /* display mode change control register except exynos4 */ 77 82 #define VIDOUT_CON 0x000 ··· 94 89 /* FIMD has totally five hardware windows. */ 95 90 #define WINDOWS_NR 5 96 91 92 + /* HW trigger flag on i80 panel. */ 93 + #define I80_HW_TRG (1 << 1) 94 + 97 95 struct fimd_driver_data { 98 96 unsigned int timing_base; 99 97 unsigned int lcdblk_offset; 100 98 unsigned int lcdblk_vt_shift; 101 99 unsigned int lcdblk_bypass_shift; 102 100 unsigned int lcdblk_mic_bypass_shift; 101 + unsigned int trg_type; 103 102 104 103 unsigned int has_shadowcon:1; 105 104 unsigned int has_clksel:1; ··· 111 102 unsigned int has_vidoutcon:1; 112 103 unsigned int has_vtsel:1; 113 104 unsigned int has_mic_bypass:1; 105 + unsigned int has_dp_clk:1; 106 + unsigned int has_hw_trigger:1; 107 + unsigned int has_trigger_per_te:1; 114 108 }; 115 109 116 110 static struct fimd_driver_data s3c64xx_fimd_driver_data = { 117 111 .timing_base = 0x0, 118 112 .has_clksel = 1, 119 113 .has_limited_fmt = 1, 114 + .has_hw_trigger = 1, 120 115 }; 121 116 122 117 static struct fimd_driver_data exynos3_fimd_driver_data = { 123 118 .timing_base = 0x20000, 124 119 .lcdblk_offset = 0x210, 125 120 .lcdblk_bypass_shift = 1, 121 + .trg_type = I80_HW_TRG, 126 122 .has_shadowcon = 1, 127 123 .has_vidoutcon = 1, 124 + .has_trigger_per_te = 1, 128 125 }; 129 126 130 127 static struct fimd_driver_data exynos4_fimd_driver_data = { ··· 147 132 .lcdblk_offset = 0x210, 148 133 .lcdblk_vt_shift = 10, 149 134 .lcdblk_bypass_shift = 1, 135 + .trg_type = I80_HW_TRG, 150 136 .has_shadowcon = 1, 151 137 .has_vidoutcon = 1, 152 138 .has_vtsel = 1, 139 + .has_trigger_per_te = 1, 153 140 }; 154 141 155 142 static struct fimd_driver_data exynos5_fimd_driver_data = { ··· 162 145 .has_shadowcon = 1, 163 146 .has_vidoutcon = 1, 164 147 .has_vtsel = 1, 148 + .has_dp_clk = 1, 165 149 }; 166 150 167 151 static struct fimd_driver_data exynos5420_fimd_driver_data = { ··· 171 153 .lcdblk_vt_shift = 24, 172 154 .lcdblk_bypass_shift = 15, 173 155 .lcdblk_mic_bypass_shift = 11, 156 + .trg_type = I80_HW_TRG, 174 157 .has_shadowcon = 1, 175 158 .has_vidoutcon = 1, 176 159 .has_vtsel = 1, 177 160 .has_mic_bypass = 1, 161 + .has_dp_clk = 1, 162 + .has_hw_trigger = 1, 163 + .has_trigger_per_te = 1, 178 164 }; 179 165 180 166 struct fimd_context { ··· 204 182 atomic_t win_updated; 205 183 atomic_t triggering; 206 184 207 - struct fimd_driver_data *driver_data; 185 + const struct fimd_driver_data *driver_data; 208 186 struct drm_encoder *encoder; 187 + struct exynos_drm_clk dp_clk; 209 188 }; 210 189 211 190 static const struct of_device_id fimd_driver_dt_match[] = { ··· 241 218 DRM_FORMAT_XRGB8888, 242 219 DRM_FORMAT_ARGB8888, 243 220 }; 244 - 245 - static inline struct fimd_driver_data *drm_fimd_get_driver_data( 246 - struct platform_device *pdev) 247 - { 248 - const struct of_device_id *of_id = 249 - of_match_device(fimd_driver_dt_match, &pdev->dev); 250 - 251 - return (struct fimd_driver_data *)of_id->data; 252 - } 253 221 254 222 static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) 255 223 { ··· 414 400 return (clkdiv < 0x100) ? clkdiv : 0xff; 415 401 } 416 402 403 + static void fimd_setup_trigger(struct fimd_context *ctx) 404 + { 405 + void __iomem *timing_base = ctx->regs + ctx->driver_data->timing_base; 406 + u32 trg_type = ctx->driver_data->trg_type; 407 + u32 val = readl(timing_base + TRIGCON); 408 + 409 + val &= ~(TRGMODE_ENABLE); 410 + 411 + if (trg_type == I80_HW_TRG) { 412 + if (ctx->driver_data->has_hw_trigger) 413 + val |= HWTRGEN_ENABLE | HWTRGMASK_ENABLE; 414 + if (ctx->driver_data->has_trigger_per_te) 415 + val |= HWTRIGEN_PER_ENABLE; 416 + } else { 417 + val |= TRGMODE_ENABLE; 418 + } 419 + 420 + writel(val, timing_base + TRIGCON); 421 + } 422 + 417 423 static void fimd_commit(struct exynos_drm_crtc *crtc) 418 424 { 419 425 struct fimd_context *ctx = crtc->ctx; 420 426 struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; 421 - struct fimd_driver_data *driver_data = ctx->driver_data; 427 + const struct fimd_driver_data *driver_data = ctx->driver_data; 422 428 void *timing_base = ctx->regs + driver_data->timing_base; 423 429 u32 val, clkdiv; 424 430 ··· 528 494 VIDTCON2_LINEVAL_E(mode->vdisplay - 1) | 529 495 VIDTCON2_HOZVAL_E(mode->hdisplay - 1); 530 496 writel(val, ctx->regs + driver_data->timing_base + VIDTCON2); 497 + 498 + fimd_setup_trigger(ctx); 531 499 532 500 /* 533 501 * fields of register with prefix '_F' would be updated ··· 863 827 static void fimd_trigger(struct device *dev) 864 828 { 865 829 struct fimd_context *ctx = dev_get_drvdata(dev); 866 - struct fimd_driver_data *driver_data = ctx->driver_data; 830 + const struct fimd_driver_data *driver_data = ctx->driver_data; 867 831 void *timing_base = ctx->regs + driver_data->timing_base; 868 832 u32 reg; 869 833 ··· 878 842 atomic_set(&ctx->triggering, 1); 879 843 880 844 reg = readl(timing_base + TRIGCON); 881 - reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE); 845 + reg |= (TRGMODE_ENABLE | SWTRGCMD_ENABLE); 882 846 writel(reg, timing_base + TRIGCON); 883 847 884 848 /* ··· 892 856 static void fimd_te_handler(struct exynos_drm_crtc *crtc) 893 857 { 894 858 struct fimd_context *ctx = crtc->ctx; 859 + u32 trg_type = ctx->driver_data->trg_type; 895 860 896 861 /* Checks the crtc is detached already from encoder */ 897 862 if (ctx->pipe < 0 || !ctx->drm_dev) 898 863 return; 864 + 865 + if (trg_type == I80_HW_TRG) 866 + goto out; 899 867 900 868 /* 901 869 * If there is a page flip request, triggers and handles the page flip ··· 908 868 if (atomic_add_unless(&ctx->win_updated, -1, 0)) 909 869 fimd_trigger(ctx->dev); 910 870 871 + out: 911 872 /* Wakes up vsync event queue */ 912 873 if (atomic_read(&ctx->wait_vsync_event)) { 913 874 atomic_set(&ctx->wait_vsync_event, 0); ··· 919 878 drm_crtc_handle_vblank(&ctx->crtc->base); 920 879 } 921 880 922 - static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) 881 + static void fimd_dp_clock_enable(struct exynos_drm_clk *clk, bool enable) 923 882 { 924 - struct fimd_context *ctx = crtc->ctx; 925 - u32 val; 883 + struct fimd_context *ctx = container_of(clk, struct fimd_context, 884 + dp_clk); 885 + u32 val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; 926 886 927 - /* 928 - * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE 929 - * clock. On these SoCs the bootloader may enable it but any 930 - * power domain off/on will reset it to disable state. 931 - */ 932 - if (ctx->driver_data != &exynos5_fimd_driver_data || 933 - ctx->driver_data != &exynos5420_fimd_driver_data) 934 - return; 935 - 936 - val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; 937 887 writel(val, ctx->regs + DP_MIE_CLKCON); 938 888 } 939 889 ··· 934 902 .commit = fimd_commit, 935 903 .enable_vblank = fimd_enable_vblank, 936 904 .disable_vblank = fimd_disable_vblank, 937 - .wait_for_vblank = fimd_wait_for_vblank, 938 905 .atomic_begin = fimd_atomic_begin, 939 906 .update_plane = fimd_update_plane, 940 907 .disable_plane = fimd_disable_plane, 941 908 .atomic_flush = fimd_atomic_flush, 942 909 .te_handler = fimd_te_handler, 943 - .clock_enable = fimd_dp_clock_enable, 944 910 }; 945 911 946 912 static irqreturn_t fimd_irq_handler(int irq, void *dev_id) ··· 1017 987 if (IS_ERR(ctx->crtc)) 1018 988 return PTR_ERR(ctx->crtc); 1019 989 990 + if (ctx->driver_data->has_dp_clk) { 991 + ctx->dp_clk.enable = fimd_dp_clock_enable; 992 + ctx->crtc->pipe_clk = &ctx->dp_clk; 993 + } 994 + 1020 995 if (ctx->encoder) 1021 996 exynos_dpi_bind(drm_dev, ctx->encoder); 1022 997 ··· 1070 1035 1071 1036 ctx->dev = dev; 1072 1037 ctx->suspended = true; 1073 - ctx->driver_data = drm_fimd_get_driver_data(pdev); 1038 + ctx->driver_data = of_device_get_match_data(dev); 1074 1039 1075 1040 if (of_property_read_bool(dev->of_node, "samsung,invert-vden")) 1076 1041 ctx->vidcon1 |= VIDCON1_INV_VDEN;
+2 -1
drivers/gpu/drm/exynos/exynos_drm_mic.c
··· 129 129 } else 130 130 val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); 131 131 132 - regmap_write(mic->sysreg, DSD_CFG_MUX, val); 132 + ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); 133 133 if (ret) 134 134 DRM_ERROR("mic: Failed to read system register\n"); 135 135 } ··· 457 457 "samsung,disp-syscon"); 458 458 if (IS_ERR(mic->sysreg)) { 459 459 DRM_ERROR("mic: Failed to get system register.\n"); 460 + ret = PTR_ERR(mic->sysreg); 460 461 goto err; 461 462 } 462 463
+7 -5
drivers/gpu/drm/exynos/exynos_drm_plane.c
··· 11 11 12 12 #include <drm/drmP.h> 13 13 14 - #include <drm/exynos_drm.h> 15 - #include <drm/drm_plane_helper.h> 14 + #include <drm/drm_atomic.h> 16 15 #include <drm/drm_atomic_helper.h> 16 + #include <drm/drm_plane_helper.h> 17 + #include <drm/exynos_drm.h> 17 18 #include "exynos_drm_drv.h" 18 19 #include "exynos_drm_crtc.h" 19 20 #include "exynos_drm_fb.h" ··· 58 57 } 59 58 60 59 static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) 61 - 62 60 { 63 61 struct drm_plane_state *state = &exynos_state->base; 64 - struct drm_crtc *crtc = exynos_state->base.crtc; 65 - struct drm_display_mode *mode = &crtc->state->adjusted_mode; 62 + struct drm_crtc *crtc = state->crtc; 63 + struct drm_crtc_state *crtc_state = 64 + drm_atomic_get_existing_crtc_state(state->state, crtc); 65 + struct drm_display_mode *mode = &crtc_state->adjusted_mode; 66 66 int crtc_x, crtc_y; 67 67 unsigned int crtc_w, crtc_h; 68 68 unsigned int src_x, src_y;
+3 -8
drivers/gpu/drm/exynos/exynos_drm_rotator.c
··· 15 15 #include <linux/io.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/clk.h> 18 + #include <linux/of_device.h> 18 19 #include <linux/pm_runtime.h> 19 20 20 21 #include <drm/drmP.h> ··· 697 696 struct device *dev = &pdev->dev; 698 697 struct rot_context *rot; 699 698 struct exynos_drm_ippdrv *ippdrv; 700 - const struct of_device_id *match; 701 699 int ret; 702 700 703 701 if (!dev->of_node) { ··· 708 708 if (!rot) 709 709 return -ENOMEM; 710 710 711 - match = of_match_node(exynos_rotator_match, dev->of_node); 712 - if (!match) { 713 - dev_err(dev, "failed to match node\n"); 714 - return -ENODEV; 715 - } 716 - rot->limit_tbl = (struct rot_limit_table *)match->data; 717 - 711 + rot->limit_tbl = (struct rot_limit_table *) 712 + of_device_get_match_data(dev); 718 713 rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 719 714 rot->regs = devm_ioremap_resource(dev, rot->regs_res); 720 715 if (IS_ERR(rot->regs))
+328 -404
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 7 7 * 8 8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c 9 9 * 10 - * This program is free software; you can redistribute it and/or modify it 11 - * under the terms of the GNU General Public License as published by the 12 - * Free Software Foundation; either version 2 of the License, or (at your 10 + * This program is free software; you can redistribute it and/or modify it 11 + * under the terms of the GNU General Public License as published by the 12 + * Free Software Foundation; either version 2 of the License, or (at your 13 13 * option) any later version. 14 14 * 15 15 */ ··· 49 49 50 50 /* AVI header and aspect ratio */ 51 51 #define HDMI_AVI_VERSION 0x02 52 - #define HDMI_AVI_LENGTH 0x0D 52 + #define HDMI_AVI_LENGTH 0x0d 53 53 54 54 /* AUI header info */ 55 - #define HDMI_AUI_VERSION 0x01 56 - #define HDMI_AUI_LENGTH 0x0A 57 - #define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8 58 - #define AVI_4_3_CENTER_RATIO 0x9 59 - #define AVI_16_9_CENTER_RATIO 0xa 55 + #define HDMI_AUI_VERSION 0x01 56 + #define HDMI_AUI_LENGTH 0x0a 57 + 58 + /* AVI active format aspect ratio */ 59 + #define AVI_SAME_AS_PIC_ASPECT_RATIO 0x08 60 + #define AVI_4_3_CENTER_RATIO 0x09 61 + #define AVI_16_9_CENTER_RATIO 0x0a 60 62 61 63 enum hdmi_type { 62 64 HDMI_TYPE13, ··· 92 90 "vdd_pll", 93 91 }; 94 92 93 + struct hdmiphy_config { 94 + int pixel_clock; 95 + u8 conf[32]; 96 + }; 97 + 98 + struct hdmiphy_configs { 99 + int count; 100 + const struct hdmiphy_config *data; 101 + }; 102 + 103 + struct string_array_spec { 104 + int count; 105 + const char * const *data; 106 + }; 107 + 108 + #define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a } 109 + 95 110 struct hdmi_driver_data { 96 111 unsigned int type; 97 - const struct hdmiphy_config *phy_confs; 98 - unsigned int phy_conf_count; 99 112 unsigned int is_apb_phy:1; 113 + unsigned int has_sysreg:1; 114 + struct hdmiphy_configs phy_confs; 115 + struct string_array_spec clk_gates; 116 + /* 117 + * Array of triplets (p_off, p_on, clock), where p_off and p_on are 118 + * required parents of clock when HDMI-PHY is respectively off or on. 119 + */ 120 + struct string_array_spec clk_muxes; 100 121 }; 101 122 102 123 struct hdmi_context { ··· 141 116 struct gpio_desc *hpd_gpio; 142 117 int irq; 143 118 struct regmap *pmureg; 144 - struct clk *hdmi; 145 - struct clk *sclk_hdmi; 146 - struct clk *sclk_pixel; 147 - struct clk *sclk_hdmiphy; 148 - struct clk *mout_hdmi; 119 + struct regmap *sysreg; 120 + struct clk **clk_gates; 121 + struct clk **clk_muxes; 149 122 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)]; 150 123 struct regulator *reg_hdmi_en; 151 124 }; ··· 158 135 return container_of(c, struct hdmi_context, connector); 159 136 } 160 137 161 - struct hdmiphy_config { 162 - int pixel_clock; 163 - u8 conf[32]; 164 - }; 165 - 166 - /* list of phy config settings */ 167 138 static const struct hdmiphy_config hdmiphy_v13_configs[] = { 168 139 { 169 140 .pixel_clock = 27000000, ··· 518 501 }, 519 502 }; 520 503 521 - static struct hdmi_driver_data exynos5420_hdmi_driver_data = { 522 - .type = HDMI_TYPE14, 523 - .phy_confs = hdmiphy_5420_configs, 524 - .phy_conf_count = ARRAY_SIZE(hdmiphy_5420_configs), 525 - .is_apb_phy = 1, 504 + static const struct hdmiphy_config hdmiphy_5433_configs[] = { 505 + { 506 + .pixel_clock = 27000000, 507 + .conf = { 508 + 0x01, 0x51, 0x22, 0x51, 0x08, 0xfc, 0x88, 0x46, 509 + 0x72, 0x50, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5, 510 + 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30, 511 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 512 + }, 513 + }, 514 + { 515 + .pixel_clock = 27027000, 516 + .conf = { 517 + 0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3, 518 + 0x71, 0x50, 0x24, 0x14, 0x24, 0x0f, 0x7c, 0xa5, 519 + 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30, 520 + 0x28, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 521 + }, 522 + }, 523 + { 524 + .pixel_clock = 40000000, 525 + .conf = { 526 + 0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02, 527 + 0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC, 528 + 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30, 529 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 530 + }, 531 + }, 532 + { 533 + .pixel_clock = 50000000, 534 + .conf = { 535 + 0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3, 536 + 0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC, 537 + 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30, 538 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 539 + }, 540 + }, 541 + { 542 + .pixel_clock = 65000000, 543 + .conf = { 544 + 0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6, 545 + 0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC, 546 + 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30, 547 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 548 + }, 549 + }, 550 + { 551 + .pixel_clock = 74176000, 552 + .conf = { 553 + 0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42, 554 + 0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC, 555 + 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30, 556 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 557 + }, 558 + }, 559 + { 560 + .pixel_clock = 74250000, 561 + .conf = { 562 + 0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2, 563 + 0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC, 564 + 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30, 565 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 566 + }, 567 + }, 568 + { 569 + .pixel_clock = 108000000, 570 + .conf = { 571 + 0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02, 572 + 0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC, 573 + 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30, 574 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40, 575 + }, 576 + }, 577 + { 578 + .pixel_clock = 148500000, 579 + .conf = { 580 + 0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1, 581 + 0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5, 582 + 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30, 583 + 0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40, 584 + }, 585 + }, 526 586 }; 527 587 528 - static struct hdmi_driver_data exynos4212_hdmi_driver_data = { 529 - .type = HDMI_TYPE14, 530 - .phy_confs = hdmiphy_v14_configs, 531 - .phy_conf_count = ARRAY_SIZE(hdmiphy_v14_configs), 532 - .is_apb_phy = 0, 588 + static const char * const hdmi_clk_gates4[] = { 589 + "hdmi", "sclk_hdmi" 533 590 }; 534 591 535 - static struct hdmi_driver_data exynos4210_hdmi_driver_data = { 592 + static const char * const hdmi_clk_muxes4[] = { 593 + "sclk_pixel", "sclk_hdmiphy", "mout_hdmi" 594 + }; 595 + 596 + static const char * const hdmi_clk_gates5433[] = { 597 + "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk" 598 + }; 599 + 600 + static const char * const hdmi_clk_muxes5433[] = { 601 + "oscclk", "tmds_clko", "tmds_clko_user", 602 + "oscclk", "pixel_clko", "pixel_clko_user" 603 + }; 604 + 605 + static const struct hdmi_driver_data exynos4210_hdmi_driver_data = { 536 606 .type = HDMI_TYPE13, 537 - .phy_confs = hdmiphy_v13_configs, 538 - .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs), 539 - .is_apb_phy = 0, 607 + .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v13_configs), 608 + .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4), 609 + .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4), 610 + }; 611 + 612 + static const struct hdmi_driver_data exynos4212_hdmi_driver_data = { 613 + .type = HDMI_TYPE14, 614 + .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v14_configs), 615 + .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4), 616 + .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4), 617 + }; 618 + 619 + static const struct hdmi_driver_data exynos5420_hdmi_driver_data = { 620 + .type = HDMI_TYPE14, 621 + .is_apb_phy = 1, 622 + .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5420_configs), 623 + .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4), 624 + .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4), 625 + }; 626 + 627 + static const struct hdmi_driver_data exynos5433_hdmi_driver_data = { 628 + .type = HDMI_TYPE14, 629 + .is_apb_phy = 1, 630 + .has_sysreg = 1, 631 + .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5433_configs), 632 + .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates5433), 633 + .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes5433), 540 634 }; 541 635 542 636 static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id) ··· 713 585 } 714 586 } 715 587 716 - static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) 588 + static int hdmi_clk_enable_gates(struct hdmi_context *hdata) 717 589 { 718 - #define DUMPREG(reg_id) \ 719 - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 720 - readl(hdata->regs + reg_id)) 721 - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); 722 - DUMPREG(HDMI_INTC_FLAG); 723 - DUMPREG(HDMI_INTC_CON); 724 - DUMPREG(HDMI_HPD_STATUS); 725 - DUMPREG(HDMI_V13_PHY_RSTOUT); 726 - DUMPREG(HDMI_V13_PHY_VPLL); 727 - DUMPREG(HDMI_V13_PHY_CMU); 728 - DUMPREG(HDMI_V13_CORE_RSTOUT); 590 + int i, ret; 729 591 730 - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); 731 - DUMPREG(HDMI_CON_0); 732 - DUMPREG(HDMI_CON_1); 733 - DUMPREG(HDMI_CON_2); 734 - DUMPREG(HDMI_SYS_STATUS); 735 - DUMPREG(HDMI_V13_PHY_STATUS); 736 - DUMPREG(HDMI_STATUS_EN); 737 - DUMPREG(HDMI_HPD); 738 - DUMPREG(HDMI_MODE_SEL); 739 - DUMPREG(HDMI_V13_HPD_GEN); 740 - DUMPREG(HDMI_V13_DC_CONTROL); 741 - DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN); 592 + for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) { 593 + ret = clk_prepare_enable(hdata->clk_gates[i]); 594 + if (!ret) 595 + continue; 742 596 743 - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); 744 - DUMPREG(HDMI_H_BLANK_0); 745 - DUMPREG(HDMI_H_BLANK_1); 746 - DUMPREG(HDMI_V13_V_BLANK_0); 747 - DUMPREG(HDMI_V13_V_BLANK_1); 748 - DUMPREG(HDMI_V13_V_BLANK_2); 749 - DUMPREG(HDMI_V13_H_V_LINE_0); 750 - DUMPREG(HDMI_V13_H_V_LINE_1); 751 - DUMPREG(HDMI_V13_H_V_LINE_2); 752 - DUMPREG(HDMI_VSYNC_POL); 753 - DUMPREG(HDMI_INT_PRO_MODE); 754 - DUMPREG(HDMI_V13_V_BLANK_F_0); 755 - DUMPREG(HDMI_V13_V_BLANK_F_1); 756 - DUMPREG(HDMI_V13_V_BLANK_F_2); 757 - DUMPREG(HDMI_V13_H_SYNC_GEN_0); 758 - DUMPREG(HDMI_V13_H_SYNC_GEN_1); 759 - DUMPREG(HDMI_V13_H_SYNC_GEN_2); 760 - DUMPREG(HDMI_V13_V_SYNC_GEN_1_0); 761 - DUMPREG(HDMI_V13_V_SYNC_GEN_1_1); 762 - DUMPREG(HDMI_V13_V_SYNC_GEN_1_2); 763 - DUMPREG(HDMI_V13_V_SYNC_GEN_2_0); 764 - DUMPREG(HDMI_V13_V_SYNC_GEN_2_1); 765 - DUMPREG(HDMI_V13_V_SYNC_GEN_2_2); 766 - DUMPREG(HDMI_V13_V_SYNC_GEN_3_0); 767 - DUMPREG(HDMI_V13_V_SYNC_GEN_3_1); 768 - DUMPREG(HDMI_V13_V_SYNC_GEN_3_2); 597 + dev_err(hdata->dev, "Cannot enable clock '%s', %d\n", 598 + hdata->drv_data->clk_gates.data[i], ret); 599 + while (i--) 600 + clk_disable_unprepare(hdata->clk_gates[i]); 601 + return ret; 602 + } 769 603 770 - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); 771 - DUMPREG(HDMI_TG_CMD); 772 - DUMPREG(HDMI_TG_H_FSZ_L); 773 - DUMPREG(HDMI_TG_H_FSZ_H); 774 - DUMPREG(HDMI_TG_HACT_ST_L); 775 - DUMPREG(HDMI_TG_HACT_ST_H); 776 - DUMPREG(HDMI_TG_HACT_SZ_L); 777 - DUMPREG(HDMI_TG_HACT_SZ_H); 778 - DUMPREG(HDMI_TG_V_FSZ_L); 779 - DUMPREG(HDMI_TG_V_FSZ_H); 780 - DUMPREG(HDMI_TG_VSYNC_L); 781 - DUMPREG(HDMI_TG_VSYNC_H); 782 - DUMPREG(HDMI_TG_VSYNC2_L); 783 - DUMPREG(HDMI_TG_VSYNC2_H); 784 - DUMPREG(HDMI_TG_VACT_ST_L); 785 - DUMPREG(HDMI_TG_VACT_ST_H); 786 - DUMPREG(HDMI_TG_VACT_SZ_L); 787 - DUMPREG(HDMI_TG_VACT_SZ_H); 788 - DUMPREG(HDMI_TG_FIELD_CHG_L); 789 - DUMPREG(HDMI_TG_FIELD_CHG_H); 790 - DUMPREG(HDMI_TG_VACT_ST2_L); 791 - DUMPREG(HDMI_TG_VACT_ST2_H); 792 - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); 793 - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); 794 - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); 795 - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); 796 - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); 797 - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); 798 - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); 799 - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); 800 - #undef DUMPREG 604 + return 0; 801 605 } 802 606 803 - static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) 607 + static void hdmi_clk_disable_gates(struct hdmi_context *hdata) 804 608 { 609 + int i = hdata->drv_data->clk_gates.count; 610 + 611 + while (i--) 612 + clk_disable_unprepare(hdata->clk_gates[i]); 613 + } 614 + 615 + static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy) 616 + { 617 + struct device *dev = hdata->dev; 618 + int ret = 0; 805 619 int i; 806 620 807 - #define DUMPREG(reg_id) \ 808 - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 809 - readl(hdata->regs + reg_id)) 621 + for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) { 622 + struct clk **c = &hdata->clk_muxes[i]; 810 623 811 - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); 812 - DUMPREG(HDMI_INTC_CON); 813 - DUMPREG(HDMI_INTC_FLAG); 814 - DUMPREG(HDMI_HPD_STATUS); 815 - DUMPREG(HDMI_INTC_CON_1); 816 - DUMPREG(HDMI_INTC_FLAG_1); 817 - DUMPREG(HDMI_PHY_STATUS_0); 818 - DUMPREG(HDMI_PHY_STATUS_PLL); 819 - DUMPREG(HDMI_PHY_CON_0); 820 - DUMPREG(HDMI_V14_PHY_RSTOUT); 821 - DUMPREG(HDMI_PHY_VPLL); 822 - DUMPREG(HDMI_PHY_CMU); 823 - DUMPREG(HDMI_CORE_RSTOUT); 624 + ret = clk_set_parent(c[2], c[to_phy]); 625 + if (!ret) 626 + continue; 824 627 825 - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); 826 - DUMPREG(HDMI_CON_0); 827 - DUMPREG(HDMI_CON_1); 828 - DUMPREG(HDMI_CON_2); 829 - DUMPREG(HDMI_SYS_STATUS); 830 - DUMPREG(HDMI_PHY_STATUS_0); 831 - DUMPREG(HDMI_STATUS_EN); 832 - DUMPREG(HDMI_HPD); 833 - DUMPREG(HDMI_MODE_SEL); 834 - DUMPREG(HDMI_ENC_EN); 835 - DUMPREG(HDMI_DC_CONTROL); 836 - DUMPREG(HDMI_VIDEO_PATTERN_GEN); 628 + dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n", 629 + hdata->drv_data->clk_muxes.data[i + 2], 630 + hdata->drv_data->clk_muxes.data[i + to_phy], ret); 631 + } 837 632 838 - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); 839 - DUMPREG(HDMI_H_BLANK_0); 840 - DUMPREG(HDMI_H_BLANK_1); 841 - DUMPREG(HDMI_V2_BLANK_0); 842 - DUMPREG(HDMI_V2_BLANK_1); 843 - DUMPREG(HDMI_V1_BLANK_0); 844 - DUMPREG(HDMI_V1_BLANK_1); 845 - DUMPREG(HDMI_V_LINE_0); 846 - DUMPREG(HDMI_V_LINE_1); 847 - DUMPREG(HDMI_H_LINE_0); 848 - DUMPREG(HDMI_H_LINE_1); 849 - DUMPREG(HDMI_HSYNC_POL); 850 - 851 - DUMPREG(HDMI_VSYNC_POL); 852 - DUMPREG(HDMI_INT_PRO_MODE); 853 - DUMPREG(HDMI_V_BLANK_F0_0); 854 - DUMPREG(HDMI_V_BLANK_F0_1); 855 - DUMPREG(HDMI_V_BLANK_F1_0); 856 - DUMPREG(HDMI_V_BLANK_F1_1); 857 - 858 - DUMPREG(HDMI_H_SYNC_START_0); 859 - DUMPREG(HDMI_H_SYNC_START_1); 860 - DUMPREG(HDMI_H_SYNC_END_0); 861 - DUMPREG(HDMI_H_SYNC_END_1); 862 - 863 - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0); 864 - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1); 865 - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0); 866 - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1); 867 - 868 - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0); 869 - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1); 870 - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0); 871 - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1); 872 - 873 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0); 874 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1); 875 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0); 876 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1); 877 - 878 - DUMPREG(HDMI_V_BLANK_F2_0); 879 - DUMPREG(HDMI_V_BLANK_F2_1); 880 - DUMPREG(HDMI_V_BLANK_F3_0); 881 - DUMPREG(HDMI_V_BLANK_F3_1); 882 - DUMPREG(HDMI_V_BLANK_F4_0); 883 - DUMPREG(HDMI_V_BLANK_F4_1); 884 - DUMPREG(HDMI_V_BLANK_F5_0); 885 - DUMPREG(HDMI_V_BLANK_F5_1); 886 - 887 - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0); 888 - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1); 889 - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0); 890 - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1); 891 - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0); 892 - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1); 893 - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0); 894 - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1); 895 - 896 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0); 897 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1); 898 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0); 899 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1); 900 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0); 901 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1); 902 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0); 903 - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1); 904 - 905 - DUMPREG(HDMI_VACT_SPACE_1_0); 906 - DUMPREG(HDMI_VACT_SPACE_1_1); 907 - DUMPREG(HDMI_VACT_SPACE_2_0); 908 - DUMPREG(HDMI_VACT_SPACE_2_1); 909 - DUMPREG(HDMI_VACT_SPACE_3_0); 910 - DUMPREG(HDMI_VACT_SPACE_3_1); 911 - DUMPREG(HDMI_VACT_SPACE_4_0); 912 - DUMPREG(HDMI_VACT_SPACE_4_1); 913 - DUMPREG(HDMI_VACT_SPACE_5_0); 914 - DUMPREG(HDMI_VACT_SPACE_5_1); 915 - DUMPREG(HDMI_VACT_SPACE_6_0); 916 - DUMPREG(HDMI_VACT_SPACE_6_1); 917 - 918 - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); 919 - DUMPREG(HDMI_TG_CMD); 920 - DUMPREG(HDMI_TG_H_FSZ_L); 921 - DUMPREG(HDMI_TG_H_FSZ_H); 922 - DUMPREG(HDMI_TG_HACT_ST_L); 923 - DUMPREG(HDMI_TG_HACT_ST_H); 924 - DUMPREG(HDMI_TG_HACT_SZ_L); 925 - DUMPREG(HDMI_TG_HACT_SZ_H); 926 - DUMPREG(HDMI_TG_V_FSZ_L); 927 - DUMPREG(HDMI_TG_V_FSZ_H); 928 - DUMPREG(HDMI_TG_VSYNC_L); 929 - DUMPREG(HDMI_TG_VSYNC_H); 930 - DUMPREG(HDMI_TG_VSYNC2_L); 931 - DUMPREG(HDMI_TG_VSYNC2_H); 932 - DUMPREG(HDMI_TG_VACT_ST_L); 933 - DUMPREG(HDMI_TG_VACT_ST_H); 934 - DUMPREG(HDMI_TG_VACT_SZ_L); 935 - DUMPREG(HDMI_TG_VACT_SZ_H); 936 - DUMPREG(HDMI_TG_FIELD_CHG_L); 937 - DUMPREG(HDMI_TG_FIELD_CHG_H); 938 - DUMPREG(HDMI_TG_VACT_ST2_L); 939 - DUMPREG(HDMI_TG_VACT_ST2_H); 940 - DUMPREG(HDMI_TG_VACT_ST3_L); 941 - DUMPREG(HDMI_TG_VACT_ST3_H); 942 - DUMPREG(HDMI_TG_VACT_ST4_L); 943 - DUMPREG(HDMI_TG_VACT_ST4_H); 944 - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); 945 - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); 946 - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); 947 - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); 948 - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); 949 - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); 950 - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); 951 - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); 952 - DUMPREG(HDMI_TG_3D); 953 - 954 - DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix); 955 - DUMPREG(HDMI_AVI_CON); 956 - DUMPREG(HDMI_AVI_HEADER0); 957 - DUMPREG(HDMI_AVI_HEADER1); 958 - DUMPREG(HDMI_AVI_HEADER2); 959 - DUMPREG(HDMI_AVI_CHECK_SUM); 960 - DUMPREG(HDMI_VSI_CON); 961 - DUMPREG(HDMI_VSI_HEADER0); 962 - DUMPREG(HDMI_VSI_HEADER1); 963 - DUMPREG(HDMI_VSI_HEADER2); 964 - for (i = 0; i < 7; ++i) 965 - DUMPREG(HDMI_VSI_DATA(i)); 966 - 967 - #undef DUMPREG 968 - } 969 - 970 - static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) 971 - { 972 - if (hdata->drv_data->type == HDMI_TYPE13) 973 - hdmi_v13_regs_dump(hdata, prefix); 974 - else 975 - hdmi_v14_regs_dump(hdata, prefix); 633 + return ret; 976 634 } 977 635 978 636 static u8 hdmi_chksum(struct hdmi_context *hdata, ··· 907 993 908 994 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) 909 995 { 996 + const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs; 910 997 int i; 911 998 912 - for (i = 0; i < hdata->drv_data->phy_conf_count; i++) 913 - if (hdata->drv_data->phy_confs[i].pixel_clock == pixel_clock) 999 + for (i = 0; i < confs->count; i++) 1000 + if (confs->data[i].pixel_clock == pixel_clock) 914 1001 return i; 915 1002 916 1003 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock); ··· 993 1078 994 1079 mode_ok = hdmi_mode_valid(connector, adjusted_mode); 995 1080 996 - /* just return if user desired mode exists. */ 997 1081 if (mode_ok == MODE_OK) 998 1082 return true; 999 1083 1000 1084 /* 1001 - * otherwise, find the most suitable mode among modes and change it 1002 - * to adjusted_mode. 1085 + * Find the most suitable mode and copy it to adjusted_mode. 1003 1086 */ 1004 1087 list_for_each_entry(m, &connector->modes, head) { 1005 1088 mode_ok = hdmi_mode_valid(connector, m); ··· 1042 1129 switch (bits_per_sample) { 1043 1130 case 20: 1044 1131 data_num = 2; 1045 - bit_ch = 1; 1132 + bit_ch = 1; 1046 1133 break; 1047 1134 case 24: 1048 1135 data_num = 3; 1049 - bit_ch = 1; 1136 + bit_ch = 1; 1050 1137 break; 1051 1138 default: 1052 1139 data_num = 1; 1053 - bit_ch = 0; 1140 + bit_ch = 0; 1054 1141 break; 1055 1142 } 1056 1143 ··· 1143 1230 /* choose HDMI mode */ 1144 1231 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1145 1232 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); 1146 - /* Apply Video preable and Guard band in HDMI mode only */ 1233 + /* apply video pre-amble and guard band in HDMI mode only */ 1147 1234 hdmi_reg_writeb(hdata, HDMI_CON_2, 0); 1148 1235 /* disable bluescreen */ 1149 1236 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); 1150 1237 1151 1238 if (hdata->dvi_mode) { 1152 - /* choose DVI mode */ 1153 1239 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1154 1240 HDMI_MODE_DVI_EN, HDMI_MODE_MASK); 1155 1241 hdmi_reg_writeb(hdata, HDMI_CON_2, ··· 1220 1308 1221 1309 val = (m->hsync_start - m->hdisplay - 2); 1222 1310 val |= ((m->hsync_end - m->hdisplay - 2) << 10); 1223 - val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20; 1311 + val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20; 1224 1312 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val); 1225 1313 1226 1314 /* ··· 1231 1319 1232 1320 /* Following values & calculations differ for different type of modes */ 1233 1321 if (m->flags & DRM_MODE_FLAG_INTERLACE) { 1234 - /* Interlaced Mode */ 1235 1322 val = ((m->vsync_end - m->vdisplay) / 2); 1236 1323 val |= ((m->vsync_start - m->vdisplay) / 2) << 12; 1237 1324 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val); ··· 1259 1348 1260 1349 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249); 1261 1350 } else { 1262 - /* Progressive Mode */ 1263 - 1264 1351 val = m->vtotal; 1265 1352 val |= (m->vtotal - m->vdisplay) << 11; 1266 1353 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val); ··· 1274 1365 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2, 1275 1366 m->vtotal - m->vdisplay); 1276 1367 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay); 1277 - hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248); 1278 1368 } 1279 1369 1280 - /* Timing generator registers */ 1281 1370 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); 1282 1371 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); 1283 1372 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); 1284 1373 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); 1285 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1); 1286 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233); 1287 - hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233); 1288 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1); 1289 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233); 1290 - hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1); 1291 - hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233); 1292 1374 } 1293 1375 1294 1376 static void hdmi_v14_mode_apply(struct hdmi_context *hdata) ··· 1290 1390 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal); 1291 1391 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal); 1292 1392 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1, 1293 - (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0); 1393 + (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0); 1294 1394 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, 1295 1395 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0); 1296 1396 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, ··· 1304 1404 1305 1405 /* Following values & calculations differ for different type of modes */ 1306 1406 if (m->flags & DRM_MODE_FLAG_INTERLACE) { 1307 - /* Interlaced Mode */ 1308 1407 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2, 1309 1408 (m->vsync_end - m->vdisplay) / 2); 1310 1409 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2, ··· 1336 1437 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0); 1337 1438 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0); 1338 1439 } else { 1339 - /* Progressive Mode */ 1340 1440 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2, 1341 1441 m->vsync_end - m->vdisplay); 1342 1442 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2, ··· 1352 1454 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2, 1353 1455 m->vtotal - m->vdisplay); 1354 1456 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay); 1355 - hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248); 1356 - hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x47b); 1357 - hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x6ae); 1358 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233); 1359 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233); 1360 - hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233); 1361 1457 } 1362 1458 1363 - /* Following values & calculations are same irrespective of mode type */ 1364 1459 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2, 1365 1460 m->hsync_start - m->hdisplay - 2); 1366 1461 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2, ··· 1377 1486 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff); 1378 1487 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff); 1379 1488 1380 - /* Timing generator registers */ 1381 1489 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); 1382 1490 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); 1383 1491 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); 1384 1492 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); 1385 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1); 1386 - hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233); 1387 - hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1); 1388 - hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1); 1389 - hdmi_reg_writev(hdata, HDMI_TG_3D, 1, 0x0); 1493 + if (hdata->drv_data == &exynos5433_hdmi_driver_data) 1494 + hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1); 1390 1495 } 1391 1496 1392 1497 static void hdmi_mode_apply(struct hdmi_context *hdata) ··· 1392 1505 else 1393 1506 hdmi_v14_mode_apply(hdata); 1394 1507 1395 - hdmiphy_wait_for_pll(hdata); 1396 - 1397 - clk_set_parent(hdata->mout_hdmi, hdata->sclk_hdmiphy); 1398 - 1399 - /* enable HDMI and timing generator */ 1400 1508 hdmi_start(hdata, true); 1401 1509 } 1402 1510 1403 1511 static void hdmiphy_conf_reset(struct hdmi_context *hdata) 1404 1512 { 1405 - clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel); 1406 - 1407 - /* reset hdmiphy */ 1513 + hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1); 1514 + usleep_range(10000, 12000); 1515 + hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1); 1516 + usleep_range(10000, 12000); 1408 1517 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); 1409 1518 usleep_range(10000, 12000); 1410 - hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT); 1519 + hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT); 1411 1520 usleep_range(10000, 12000); 1521 + } 1522 + 1523 + static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable) 1524 + { 1525 + u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET; 1526 + 1527 + if (hdata->drv_data == &exynos5433_hdmi_driver_data) 1528 + writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE); 1412 1529 } 1413 1530 1414 1531 static void hdmiphy_conf_apply(struct hdmi_context *hdata) 1415 1532 { 1416 1533 int ret; 1417 - int i; 1534 + const u8 *phy_conf; 1418 1535 1419 - /* pixel clock */ 1420 - i = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000); 1421 - if (i < 0) { 1536 + ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000); 1537 + if (ret < 0) { 1422 1538 DRM_ERROR("failed to find hdmiphy conf\n"); 1423 1539 return; 1424 1540 } 1541 + phy_conf = hdata->drv_data->phy_confs.data[ret].conf; 1425 1542 1426 - ret = hdmiphy_reg_write_buf(hdata, 0, 1427 - hdata->drv_data->phy_confs[i].conf, 32); 1543 + hdmi_clk_set_parents(hdata, false); 1544 + 1545 + hdmiphy_conf_reset(hdata); 1546 + 1547 + hdmiphy_enable_mode_set(hdata, true); 1548 + ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32); 1428 1549 if (ret) { 1429 1550 DRM_ERROR("failed to configure hdmiphy\n"); 1430 1551 return; 1431 1552 } 1432 - 1553 + hdmiphy_enable_mode_set(hdata, false); 1554 + hdmi_clk_set_parents(hdata, true); 1433 1555 usleep_range(10000, 12000); 1556 + hdmiphy_wait_for_pll(hdata); 1434 1557 } 1435 1558 1436 1559 static void hdmi_conf_apply(struct hdmi_context *hdata) 1437 1560 { 1438 - hdmiphy_conf_reset(hdata); 1439 1561 hdmiphy_conf_apply(hdata); 1440 - 1441 1562 hdmi_start(hdata, false); 1442 1563 hdmi_conf_init(hdata); 1443 - 1444 1564 hdmi_audio_init(hdata); 1445 - 1446 - /* setting core registers */ 1447 1565 hdmi_mode_apply(hdata); 1448 1566 hdmi_audio_control(hdata, true); 1449 - 1450 - hdmi_regs_dump(hdata, "start"); 1451 1567 } 1452 1568 1453 1569 static void hdmi_mode_set(struct drm_encoder *encoder, ··· 1469 1579 hdata->cea_video_id = drm_match_cea_mode(mode); 1470 1580 } 1471 1581 1582 + static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) 1583 + { 1584 + if (!hdata->sysreg) 1585 + return; 1586 + 1587 + regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY, 1588 + SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0); 1589 + } 1590 + 1472 1591 static void hdmi_enable(struct drm_encoder *encoder) 1473 1592 { 1474 1593 struct hdmi_context *hdata = encoder_to_hdmi(encoder); ··· 1490 1591 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk)) 1491 1592 DRM_DEBUG_KMS("failed to enable regulator bulk\n"); 1492 1593 1493 - /* set pmu hdmiphy control bit to enable hdmiphy */ 1494 1594 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1495 1595 PMU_HDMI_PHY_ENABLE_BIT, 1); 1596 + 1597 + hdmi_set_refclk(hdata, true); 1598 + 1599 + hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN); 1496 1600 1497 1601 hdmi_conf_apply(hdata); 1498 1602 ··· 1525 1623 if (funcs && funcs->disable) 1526 1624 (*funcs->disable)(crtc); 1527 1625 1528 - /* HDMI System Disable */ 1529 1626 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN); 1530 1627 1531 1628 cancel_delayed_work(&hdata->hotplug_work); 1532 1629 1533 - /* reset pmu hdmiphy control bit to disable hdmiphy */ 1630 + hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN); 1631 + 1632 + hdmi_set_refclk(hdata, false); 1633 + 1534 1634 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1535 1635 PMU_HDMI_PHY_ENABLE_BIT, 0); 1536 1636 ··· 1574 1670 return IRQ_HANDLED; 1575 1671 } 1576 1672 1673 + static int hdmi_clks_get(struct hdmi_context *hdata, 1674 + const struct string_array_spec *names, 1675 + struct clk **clks) 1676 + { 1677 + struct device *dev = hdata->dev; 1678 + int i; 1679 + 1680 + for (i = 0; i < names->count; ++i) { 1681 + struct clk *clk = devm_clk_get(dev, names->data[i]); 1682 + 1683 + if (IS_ERR(clk)) { 1684 + int ret = PTR_ERR(clk); 1685 + 1686 + dev_err(dev, "Cannot get clock %s, %d\n", 1687 + names->data[i], ret); 1688 + 1689 + return ret; 1690 + } 1691 + 1692 + clks[i] = clk; 1693 + } 1694 + 1695 + return 0; 1696 + } 1697 + 1698 + static int hdmi_clk_init(struct hdmi_context *hdata) 1699 + { 1700 + const struct hdmi_driver_data *drv_data = hdata->drv_data; 1701 + int count = drv_data->clk_gates.count + drv_data->clk_muxes.count; 1702 + struct device *dev = hdata->dev; 1703 + struct clk **clks; 1704 + int ret; 1705 + 1706 + if (!count) 1707 + return 0; 1708 + 1709 + clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL); 1710 + if (!clks) 1711 + return -ENOMEM; 1712 + 1713 + hdata->clk_gates = clks; 1714 + hdata->clk_muxes = clks + drv_data->clk_gates.count; 1715 + 1716 + ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates); 1717 + if (ret) 1718 + return ret; 1719 + 1720 + return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes); 1721 + } 1722 + 1723 + 1577 1724 static int hdmi_resources_init(struct hdmi_context *hdata) 1578 1725 { 1579 1726 struct device *dev = hdata->dev; ··· 1643 1688 DRM_ERROR("failed to get GPIO irq\n"); 1644 1689 return hdata->irq; 1645 1690 } 1646 - /* get clocks, power */ 1647 - hdata->hdmi = devm_clk_get(dev, "hdmi"); 1648 - if (IS_ERR(hdata->hdmi)) { 1649 - DRM_ERROR("failed to get clock 'hdmi'\n"); 1650 - ret = PTR_ERR(hdata->hdmi); 1651 - goto fail; 1652 - } 1653 - hdata->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); 1654 - if (IS_ERR(hdata->sclk_hdmi)) { 1655 - DRM_ERROR("failed to get clock 'sclk_hdmi'\n"); 1656 - ret = PTR_ERR(hdata->sclk_hdmi); 1657 - goto fail; 1658 - } 1659 - hdata->sclk_pixel = devm_clk_get(dev, "sclk_pixel"); 1660 - if (IS_ERR(hdata->sclk_pixel)) { 1661 - DRM_ERROR("failed to get clock 'sclk_pixel'\n"); 1662 - ret = PTR_ERR(hdata->sclk_pixel); 1663 - goto fail; 1664 - } 1665 - hdata->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy"); 1666 - if (IS_ERR(hdata->sclk_hdmiphy)) { 1667 - DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); 1668 - ret = PTR_ERR(hdata->sclk_hdmiphy); 1669 - goto fail; 1670 - } 1671 - hdata->mout_hdmi = devm_clk_get(dev, "mout_hdmi"); 1672 - if (IS_ERR(hdata->mout_hdmi)) { 1673 - DRM_ERROR("failed to get clock 'mout_hdmi'\n"); 1674 - ret = PTR_ERR(hdata->mout_hdmi); 1675 - goto fail; 1676 - } 1677 1691 1678 - clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel); 1692 + ret = hdmi_clk_init(hdata); 1693 + if (ret) 1694 + return ret; 1695 + 1696 + ret = hdmi_clk_set_parents(hdata, false); 1697 + if (ret) 1698 + return ret; 1679 1699 1680 1700 for (i = 0; i < ARRAY_SIZE(supply); ++i) { 1681 1701 hdata->regul_bulk[i].supply = supply[i]; ··· 1675 1745 DRM_ERROR("failed to enable hdmi-en regulator\n"); 1676 1746 1677 1747 return ret; 1678 - fail: 1679 - DRM_ERROR("HDMI resource init - failed\n"); 1680 - return ret; 1681 1748 } 1682 1749 1683 1750 static struct of_device_id hdmi_match_types[] = { ··· 1687 1760 }, { 1688 1761 .compatible = "samsung,exynos5420-hdmi", 1689 1762 .data = &exynos5420_hdmi_driver_data, 1763 + }, { 1764 + .compatible = "samsung,exynos5433-hdmi", 1765 + .data = &exynos5433_hdmi_driver_data, 1690 1766 }, { 1691 1767 /* end node */ 1692 1768 } ··· 1760 1830 static int hdmi_probe(struct platform_device *pdev) 1761 1831 { 1762 1832 struct device_node *ddc_node, *phy_node; 1763 - const struct of_device_id *match; 1764 1833 struct device *dev = &pdev->dev; 1765 1834 struct hdmi_context *hdata; 1766 1835 struct resource *res; ··· 1769 1840 if (!hdata) 1770 1841 return -ENOMEM; 1771 1842 1772 - match = of_match_device(hdmi_match_types, dev); 1773 - if (!match) 1774 - return -ENODEV; 1775 - 1776 - hdata->drv_data = match->data; 1843 + hdata->drv_data = of_device_get_match_data(dev); 1777 1844 1778 1845 platform_set_drvdata(pdev, hdata); 1779 1846 ··· 1792 1867 if (ddc_node) 1793 1868 goto out_get_ddc_adpt; 1794 1869 1795 - /* DDC i2c driver */ 1796 1870 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); 1797 1871 if (!ddc_node) { 1798 1872 DRM_ERROR("Failed to find ddc node in device tree\n"); ··· 1809 1885 if (phy_node) 1810 1886 goto out_get_phy_port; 1811 1887 1812 - /* hdmiphy i2c driver */ 1813 1888 phy_node = of_parse_phandle(dev->of_node, "phy", 0); 1814 1889 if (!phy_node) { 1815 1890 DRM_ERROR("Failed to find hdmiphy node in device tree\n"); ··· 1850 1927 DRM_ERROR("syscon regmap lookup failed.\n"); 1851 1928 ret = -EPROBE_DEFER; 1852 1929 goto err_hdmiphy; 1930 + } 1931 + 1932 + if (hdata->drv_data->has_sysreg) { 1933 + hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 1934 + "samsung,sysreg-phandle"); 1935 + if (IS_ERR(hdata->sysreg)) { 1936 + DRM_ERROR("sysreg regmap lookup failed.\n"); 1937 + ret = -EPROBE_DEFER; 1938 + goto err_hdmiphy; 1939 + } 1853 1940 } 1854 1941 1855 1942 pm_runtime_enable(dev); ··· 1908 1975 { 1909 1976 struct hdmi_context *hdata = dev_get_drvdata(dev); 1910 1977 1911 - clk_disable_unprepare(hdata->sclk_hdmi); 1912 - clk_disable_unprepare(hdata->hdmi); 1978 + hdmi_clk_disable_gates(hdata); 1913 1979 1914 1980 return 0; 1915 1981 } ··· 1918 1986 struct hdmi_context *hdata = dev_get_drvdata(dev); 1919 1987 int ret; 1920 1988 1921 - ret = clk_prepare_enable(hdata->hdmi); 1922 - if (ret < 0) { 1923 - DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); 1989 + ret = hdmi_clk_enable_gates(hdata); 1990 + if (ret < 0) 1924 1991 return ret; 1925 - } 1926 - ret = clk_prepare_enable(hdata->sclk_hdmi); 1927 - if (ret < 0) { 1928 - DRM_ERROR("Failed to prepare_enable the sclk_mixer clk [%d]\n", 1929 - ret); 1930 - return ret; 1931 - } 1932 1992 1933 1993 return 0; 1934 1994 }
+7 -62
drivers/gpu/drm/exynos/exynos_mixer.c
··· 31 31 #include <linux/clk.h> 32 32 #include <linux/regulator/consumer.h> 33 33 #include <linux/of.h> 34 + #include <linux/of_device.h> 34 35 #include <linux/component.h> 35 36 36 37 #include <drm/exynos_drm.h> ··· 104 103 105 104 struct mixer_resources mixer_res; 106 105 enum mixer_version_id mxr_ver; 107 - wait_queue_head_t wait_vsync_queue; 108 - atomic_t wait_vsync_event; 109 106 }; 110 107 111 108 struct mixer_drv_data { ··· 786 787 787 788 exynos_drm_crtc_finish_update(ctx->crtc, plane); 788 789 } 789 - 790 - /* set wait vsync event to zero and wake up queue. */ 791 - if (atomic_read(&ctx->wait_vsync_event)) { 792 - atomic_set(&ctx->wait_vsync_event, 0); 793 - wake_up(&ctx->wait_vsync_queue); 794 - } 795 790 } 796 791 797 792 out: ··· 1020 1027 mixer_vsync_set_update(mixer_ctx, true); 1021 1028 } 1022 1029 1023 - static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) 1024 - { 1025 - struct mixer_context *mixer_ctx = crtc->ctx; 1026 - int err; 1027 - 1028 - if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) 1029 - return; 1030 - 1031 - err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe); 1032 - if (err < 0) { 1033 - DRM_DEBUG_KMS("failed to acquire vblank counter\n"); 1034 - return; 1035 - } 1036 - 1037 - atomic_set(&mixer_ctx->wait_vsync_event, 1); 1038 - 1039 - /* 1040 - * wait for MIXER to signal VSYNC interrupt or return after 1041 - * timeout which is set to 50ms (refresh rate of 20). 1042 - */ 1043 - if (!wait_event_timeout(mixer_ctx->wait_vsync_queue, 1044 - !atomic_read(&mixer_ctx->wait_vsync_event), 1045 - HZ/20)) 1046 - DRM_DEBUG_KMS("vblank wait timed out.\n"); 1047 - 1048 - drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe); 1049 - } 1050 - 1051 1030 static void mixer_enable(struct exynos_drm_crtc *crtc) 1052 1031 { 1053 1032 struct mixer_context *ctx = crtc->ctx; ··· 1029 1064 return; 1030 1065 1031 1066 pm_runtime_get_sync(ctx->dev); 1067 + 1068 + exynos_drm_pipe_clk_enable(crtc, true); 1032 1069 1033 1070 mixer_vsync_set_update(ctx, false); 1034 1071 ··· 1060 1093 1061 1094 for (i = 0; i < MIXER_WIN_NR; i++) 1062 1095 mixer_disable_plane(crtc, &ctx->planes[i]); 1096 + 1097 + exynos_drm_pipe_clk_enable(crtc, false); 1063 1098 1064 1099 pm_runtime_put(ctx->dev); 1065 1100 ··· 1095 1126 .disable = mixer_disable, 1096 1127 .enable_vblank = mixer_enable_vblank, 1097 1128 .disable_vblank = mixer_disable_vblank, 1098 - .wait_for_vblank = mixer_wait_for_vblank, 1099 1129 .atomic_begin = mixer_atomic_begin, 1100 1130 .update_plane = mixer_update_plane, 1101 1131 .disable_plane = mixer_disable_plane, ··· 1121 1153 .version = MXR_VER_0_0_0_16, 1122 1154 .is_vp_enabled = 1, 1123 1155 .has_sclk = 1, 1124 - }; 1125 - 1126 - static const struct platform_device_id mixer_driver_types[] = { 1127 - { 1128 - .name = "s5p-mixer", 1129 - .driver_data = (unsigned long)&exynos4210_mxr_drv_data, 1130 - }, { 1131 - .name = "exynos5-mixer", 1132 - .driver_data = (unsigned long)&exynos5250_mxr_drv_data, 1133 - }, { 1134 - /* end node */ 1135 - } 1136 1156 }; 1137 1157 1138 1158 static struct of_device_id mixer_match_types[] = { ··· 1199 1243 static int mixer_probe(struct platform_device *pdev) 1200 1244 { 1201 1245 struct device *dev = &pdev->dev; 1202 - struct mixer_drv_data *drv; 1246 + const struct mixer_drv_data *drv; 1203 1247 struct mixer_context *ctx; 1204 1248 int ret; 1205 1249 ··· 1209 1253 return -ENOMEM; 1210 1254 } 1211 1255 1212 - if (dev->of_node) { 1213 - const struct of_device_id *match; 1214 - 1215 - match = of_match_node(mixer_match_types, dev->of_node); 1216 - drv = (struct mixer_drv_data *)match->data; 1217 - } else { 1218 - drv = (struct mixer_drv_data *) 1219 - platform_get_device_id(pdev)->driver_data; 1220 - } 1256 + drv = of_device_get_match_data(dev); 1221 1257 1222 1258 ctx->pdev = pdev; 1223 1259 ctx->dev = dev; 1224 1260 ctx->vp_enabled = drv->is_vp_enabled; 1225 1261 ctx->has_sclk = drv->has_sclk; 1226 1262 ctx->mxr_ver = drv->version; 1227 - init_waitqueue_head(&ctx->wait_vsync_queue); 1228 - atomic_set(&ctx->wait_vsync_event, 0); 1229 1263 1230 1264 platform_set_drvdata(pdev, ctx); 1231 1265 ··· 1301 1355 }, 1302 1356 .probe = mixer_probe, 1303 1357 .remove = mixer_remove, 1304 - .id_table = mixer_driver_types, 1305 1358 };
+7 -2
drivers/gpu/drm/exynos/regs-hdmi.h
··· 586 586 #define HDMI_TG_VACT_ST4_L HDMI_TG_BASE(0x0070) 587 587 #define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) 588 588 #define HDMI_TG_3D HDMI_TG_BASE(0x00F0) 589 + #define HDMI_TG_DECON_EN HDMI_TG_BASE(0x01e0) 589 590 590 591 /* HDMI PHY Registers Offsets*/ 591 - #define HDMIPHY_POWER (0x74 >> 2) 592 - #define HDMIPHY_MODE_SET_DONE (0x7c >> 2) 592 + #define HDMIPHY_POWER 0x74 593 + #define HDMIPHY_MODE_SET_DONE 0x7c 594 + #define HDMIPHY5433_MODE_SET_DONE 0x84 593 595 594 596 /* HDMI PHY Values */ 595 597 #define HDMI_PHY_POWER_ON 0x80 ··· 604 602 /* PMU Registers for PHY */ 605 603 #define PMU_HDMI_PHY_CONTROL 0x700 606 604 #define PMU_HDMI_PHY_ENABLE_BIT BIT(0) 605 + 606 + #define EXYNOS5433_SYSREG_DISP_HDMI_PHY 0x1008 607 + #define SYSREG_HDMI_REFCLK_INT_CLK 1 607 608 608 609 #endif /* SAMSUNG_REGS_HDMI_H */
+3 -3
include/video/exynos5433_decon.h
··· 179 179 #define TRIGCON_TRIGMODE_W1BUF (1 << 10) 180 180 #define TRIGCON_SWTRIGCMD_W0BUF (1 << 6) 181 181 #define TRIGCON_TRIGMODE_W0BUF (1 << 5) 182 - #define TRIGCON_HWTRIGMASK_I80_RGB (1 << 4) 183 - #define TRIGCON_HWTRIGEN_I80_RGB (1 << 3) 184 - #define TRIGCON_HWTRIG_INV_I80_RGB (1 << 2) 182 + #define TRIGCON_HWTRIGMASK (1 << 4) 183 + #define TRIGCON_HWTRIGEN (1 << 3) 184 + #define TRIGCON_HWTRIG_INV (1 << 2) 185 185 #define TRIGCON_SWTRIGCMD (1 << 1) 186 186 #define TRIGCON_SWTRIGEN (1 << 0) 187 187