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:
. Add atomic feature support
- Exynos also now supports atomic feature. However, it doesn't
guarantee atomic operation yet, and is required for more cleanups.
This time we just modified for Exynos drm driver to use atomic
interfaces instead of legacy ones. Next time, we will enhance
Exynos drm driver to support the atomic operation.
. Add iommu support
- This is a patch series according to below Exynos iommu integration
work with DT and dma-mapping subsystem,
http://lwn.net/Articles/607626/
. Consolidate Exynos drm driver initialization.
- This patch sereis resolves the issue that only the first compoments
was bound when happened deferred probing for other pipelines and
also makes the driver to be more cleanned up by moving the dispered
codes for registering kms drivers to one place.
. Add new MIC, DECON drivers, and MIPI-DSI support for Exynos5433.
- Add MIC(Mobile image compressor) driver. MIC is a new IP for Exynos5433
and later, which is used to transfer frame data to MIPI-DSI controller
compressing the data to reduce memory bandwidth.
- Add DECON driver for Exynos5433 SoC. This IP is a dislay controller
similar to Exynos7's one but this controller has much different registers
from Exynos7's ones so this driver has been implemented separately.
We will implement a helper modules for FIMD and two DECON controllers
to remove duplicated codes later.
- Add Exynos5433 SoC support to MIPI-DSI driver, and device tree
relevant patches.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (50 commits)
ARM: dts: rename the clock of MIPI DSI 'pll_clk' to 'sclk_mipi'
drm/exynos: dsi: do not set TE GPIO direction by input
drm/exynos: dsi: add support for MIC driver as a bridge
drm/exynos: dsi: add support for Exynos5433
drm/exynos: dsi: make use of array for clock access
drm/exynos: dsi: make use of driver data for static values
drm/exynos: dsi: add macros for register access
drm/exynos: dsi: rename pll_clk to sclk_clk
drm/exynos: mic: add MIC driver
of: add helper for getting endpoint node of specific identifiers
drm/exynos: add Exynos5433 decon driver
drm/exynos: fix the input prompt of Exynos7 DECON
drm/exynos: add drm_iommu_attach_device_if_possible()
drm/exynos: Add the dependency for DRM_EXYNOS to DPI/DSI/DP
drm/exynos: remove the dependency of DP driver for ARCH_EXYNOS
drm/exynos: do not wait for vblank at atomic operation
drm/exynos: Remove unused vma field of exynos_drm_gem_obj
drm/exynos: fimd: fix page fault issue with iommu
drm/exynos: iommu: improve a check for non-iommu dma_ops
drm/exynos: iommu: detach from default dma-mapping domain on init
...

+2553 -1411
+51
Documentation/devicetree/bindings/video/exynos-mic.txt
··· 1 + Device-Tree bindings for Samsung Exynos SoC mobile image compressor (MIC) 2 + 3 + MIC (mobile image compressor) resides between decon and mipi dsi. Mipi dsi is 4 + not capable to transfer high resoltuion frame data as decon can send. MIC 5 + solves this problem by compressing the frame data by 1/2 before it is 6 + transferred through mipi dsi. The compressed frame data must be uncompressed in 7 + the panel PCB. 8 + 9 + Required properties: 10 + - compatible: value should be "samsung,exynos5433-mic". 11 + - reg: physical base address and length of the MIC registers set and system 12 + register of mic. 13 + - clocks: must include clock specifiers corresponding to entries in the 14 + clock-names property. 15 + - clock-names: list of clock names sorted in the same order as the clocks 16 + property. Must contain "pclk_mic0", "sclk_rgb_vclk_to_mic0". 17 + - samsung,disp-syscon: the reference node for syscon for DISP block. 18 + - ports: contains a port which is connected to decon node and dsi node. 19 + address-cells and size-cells must 1 and 0, respectively. 20 + - port: contains an endpoint node which is connected to the endpoint in the 21 + decon node or dsi node. The reg value must be 0 and 1 respectively. 22 + 23 + Example: 24 + SoC specific DT entry: 25 + mic: mic@13930000 { 26 + compatible = "samsung,exynos5433-mic"; 27 + reg = <0x13930000 0x48>; 28 + clocks = <&cmu_disp CLK_PCLK_MIC0>, 29 + <&cmu_disp CLK_SCLK_RGB_VCLK_TO_MIC0>; 30 + clock-names = "pclk_mic0", "sclk_rgb_vclk_to_mic0"; 31 + samsung,disp-syscon = <&syscon_disp>; 32 + 33 + ports { 34 + #address-cells = <1>; 35 + #size-cells = <0>; 36 + 37 + port@0 { 38 + reg = <0>; 39 + mic_to_decon: endpoint { 40 + remote-endpoint = <&decon_to_mic>; 41 + }; 42 + }; 43 + 44 + port@1 { 45 + reg = <1>; 46 + mic_to_dsi: endpoint { 47 + remote-endpoint = <&dsi_to_mic>; 48 + }; 49 + }; 50 + }; 51 + };
+65
Documentation/devicetree/bindings/video/exynos5433-decon.txt
··· 1 + Device-Tree bindings for Samsung Exynos SoC display controller (DECON) 2 + 3 + DECON (Display and Enhancement Controller) is the Display Controller for the 4 + Exynos series of SoCs which transfers the image data from a video memory 5 + buffer to an external LCD interface. 6 + 7 + Required properties: 8 + - compatible: value should be "samsung,exynos5433-decon"; 9 + - reg: physical base address and length of the DECON registers set. 10 + - interrupts: should contain a list of all DECON IP block interrupts in the 11 + order: VSYNC, LCD_SYSTEM. The interrupt specifier format 12 + depends on the interrupt controller used. 13 + - interrupt-names: should contain the interrupt names: "vsync", "lcd_sys" 14 + in the same order as they were listed in the interrupts 15 + property. 16 + - clocks: must include clock specifiers corresponding to entries in the 17 + clock-names property. 18 + - clock-names: list of clock names sorted in the same order as the clocks 19 + property. Must contain "aclk_decon", "aclk_smmu_decon0x", 20 + "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk", 21 + "sclk_decon_eclk" 22 + - ports: contains a port which is connected to mic node. address-cells and 23 + size-cells must 1 and 0, respectively. 24 + - port: contains an endpoint node which is connected to the endpoint in the mic 25 + node. The reg value muset be 0. 26 + - i80-if-timings: specify whether the panel which is connected to decon uses 27 + i80 lcd interface or mipi video interface. This node contains 28 + no timing information as that of fimd does. Because there is 29 + no register in decon to specify i80 interface timing value, 30 + it is not needed, but make it remain to use same kind of node 31 + in fimd and exynos7 decon. 32 + 33 + Example: 34 + SoC specific DT entry: 35 + decon: decon@13800000 { 36 + compatible = "samsung,exynos5433-decon"; 37 + reg = <0x13800000 0x2104>; 38 + clocks = <&cmu_disp CLK_ACLK_DECON>, <&cmu_disp CLK_ACLK_SMMU_DECON0X>, 39 + <&cmu_disp CLK_ACLK_XIU_DECON0X>, 40 + <&cmu_disp CLK_PCLK_SMMU_DECON0X>, 41 + <&cmu_disp CLK_SCLK_DECON_VCLK>, 42 + <&cmu_disp CLK_SCLK_DECON_ECLK>; 43 + clock-names = "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", 44 + "pclk_smmu_decon0x", "sclk_decon_vclk", "sclk_decon_eclk"; 45 + interrupt-names = "vsync", "lcd_sys"; 46 + interrupts = <0 202 0>, <0 203 0>; 47 + 48 + ports { 49 + #address-cells = <1>; 50 + #size-cells = <0>; 51 + 52 + port@0 { 53 + reg = <0>; 54 + decon_to_mic: endpoint { 55 + remote-endpoint = <&mic_to_decon>; 56 + }; 57 + }; 58 + }; 59 + }; 60 + 61 + Board specific DT entry: 62 + &decon { 63 + i80-if-timings { 64 + }; 65 + };
+25 -6
Documentation/devicetree/bindings/video/exynos_dsim.txt
··· 6 6 "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */ 7 7 "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */ 8 8 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */ 9 + "samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */ 9 10 - reg: physical base address and length of the registers set for the device 10 11 - interrupts: should contain DSI interrupt 11 12 - clocks: list of clock specifiers, must contain an entry for each required 12 13 entry in clock-names 13 - - clock-names: should include "bus_clk"and "pll_clk" entries 14 + - clock-names: should include "bus_clk"and "sclk_mipi" entries 15 + the use of "pll_clk" is deprecated 14 16 - phys: list of phy specifiers, must contain an entry for each required 15 17 entry in phy-names 16 18 - phy-names: should include "dsim" entry 17 19 - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V) 18 20 - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V) 19 - - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock 21 + - samsung,pll-clock-frequency: specifies frequency of the oscillator clock 20 22 - #address-cells, #size-cells: should be set respectively to <1> and <0> 21 23 according to DSI host bindings (see MIPI DSI bindings [1]) 22 24 ··· 32 30 Device node can contain video interface port nodes according to [2]. 33 31 The following are properties specific to those nodes: 34 32 35 - port node: 36 - - reg: (required) can be 0 for input RGB/I80 port or 1 for DSI port; 33 + port node inbound: 34 + - reg: (required) must be 0. 35 + port node outbound: 36 + - reg: (required) must be 1. 37 37 38 - endpoint node of DSI port (reg = 1): 38 + endpoint node connected from mic node (reg = 0): 39 + - remote-endpoint: specifies the endpoint in mic node. This node is required 40 + for Exynos5433 mipi dsi. So mic can access to panel node 41 + thoughout this dsi node. 42 + endpoint node connected to panel node (reg = 1): 43 + - remote-endpoint: specifies the endpoint in panel node. This node is 44 + required in all kinds of exynos mipi dsi to represent 45 + the connection between mipi dsi and panel. 39 46 - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst 40 47 mode 41 48 - samsung,esc-clock-frequency: specifies DSI frequency in escape mode ··· 59 48 reg = <0x11C80000 0x10000>; 60 49 interrupts = <0 79 0>; 61 50 clocks = <&clock 286>, <&clock 143>; 62 - clock-names = "bus_clk", "pll_clk"; 51 + clock-names = "bus_clk", "sclk_mipi"; 63 52 phys = <&mipi_phy 1>; 64 53 phy-names = "dsim"; 65 54 vddcore-supply = <&vusb_reg>; ··· 83 72 #address-cells = <1>; 84 73 #size-cells = <0>; 85 74 75 + port@0 { 76 + reg = <0>; 77 + decon_to_mic: endpoint { 78 + remote-endpoint = <&mic_to_decon>; 79 + }; 80 + }; 81 + 86 82 port@1 { 83 + reg = <1>; 87 84 dsi_ep: endpoint { 88 85 reg = <0>; 89 86 samsung,burst-clock-frequency = <500000000>;
+1 -1
arch/arm/boot/dts/exynos4.dtsi
··· 167 167 phys = <&mipi_phy 1>; 168 168 phy-names = "dsim"; 169 169 clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>; 170 - clock-names = "bus_clk", "pll_clk"; 170 + clock-names = "bus_clk", "sclk_mipi"; 171 171 status = "disabled"; 172 172 #address-cells = <1>; 173 173 #size-cells = <0>;
+5 -1
drivers/gpu/drm/bridge/ps8622.c
··· 32 32 #include "drmP.h" 33 33 #include "drm_crtc.h" 34 34 #include "drm_crtc_helper.h" 35 + #include "drm_atomic_helper.h" 35 36 36 37 /* Brightness scale on the Parade chip */ 37 38 #define PS8622_MAX_BRIGHTNESS 0xff ··· 500 499 } 501 500 502 501 static const struct drm_connector_funcs ps8622_connector_funcs = { 503 - .dpms = drm_helper_connector_dpms, 502 + .dpms = drm_atomic_helper_connector_dpms, 504 503 .fill_modes = drm_helper_probe_single_connector_modes, 505 504 .detect = ps8622_detect, 506 505 .destroy = ps8622_connector_destroy, 506 + .reset = drm_atomic_helper_connector_reset, 507 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 508 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 507 509 }; 508 510 509 511 static int ps8622_attach(struct drm_bridge *bridge)
+5 -1
drivers/gpu/drm/bridge/ptn3460.c
··· 26 26 27 27 #include "drm_crtc.h" 28 28 #include "drm_crtc_helper.h" 29 + #include "drm_atomic_helper.h" 29 30 #include "drm_edid.h" 30 31 #include "drmP.h" 31 32 ··· 259 258 } 260 259 261 260 static struct drm_connector_funcs ptn3460_connector_funcs = { 262 - .dpms = drm_helper_connector_dpms, 261 + .dpms = drm_atomic_helper_connector_dpms, 263 262 .fill_modes = drm_helper_probe_single_connector_modes, 264 263 .detect = ptn3460_detect, 265 264 .destroy = ptn3460_connector_destroy, 265 + .reset = drm_atomic_helper_connector_reset, 266 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 267 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 266 268 }; 267 269 268 270 static int ptn3460_bridge_attach(struct drm_bridge *bridge)
+17 -5
drivers/gpu/drm/exynos/Kconfig
··· 24 24 help 25 25 Choose this option if you want to use Exynos FIMD for DRM. 26 26 27 - config DRM_EXYNOS7_DECON 28 - bool "Exynos DRM DECON" 27 + config DRM_EXYNOS5433_DECON 28 + bool "Exynos5433 DRM DECON" 29 29 depends on DRM_EXYNOS 30 + help 31 + Choose this option if you want to use Exynos5433 DECON for DRM. 32 + 33 + config DRM_EXYNOS7_DECON 34 + bool "Exynos7 DRM DECON" 35 + depends on DRM_EXYNOS && !FB_S3C 30 36 select FB_MODE_HELPERS 31 37 help 32 38 Choose this option if you want to use Exynos DECON for DRM. 33 39 34 40 config DRM_EXYNOS_DPI 35 41 bool "EXYNOS DRM parallel output support" 36 - depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) 42 + depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) 37 43 select DRM_PANEL 38 44 default n 39 45 help ··· 47 41 48 42 config DRM_EXYNOS_DSI 49 43 bool "EXYNOS DRM MIPI-DSI driver support" 50 - depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) 44 + depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS5433_DECON || DRM_EXYNOS7_DECON) 51 45 select DRM_MIPI_DSI 52 46 select DRM_PANEL 53 47 default n ··· 56 50 57 51 config DRM_EXYNOS_DP 58 52 bool "EXYNOS DRM DP driver support" 59 - depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) 53 + depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) 60 54 default DRM_EXYNOS 61 55 select DRM_PANEL 62 56 help ··· 103 97 depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM 104 98 help 105 99 Choose this option if you want to use Exynos GSC for DRM. 100 + 101 + config DRM_EXYNOS_MIC 102 + bool "Exynos DRM MIC" 103 + depends on (DRM_EXYNOS && DRM_EXYNOS5433_DECON) 104 + help 105 + Choose this option if you want to use Exynos MIC for DRM.
+2
drivers/gpu/drm/exynos/Makefile
··· 10 10 11 11 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o 12 12 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 13 + exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o 13 14 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o 14 15 exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o 15 16 exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o ··· 22 21 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMC) += exynos_drm_fimc.o 23 22 exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR) += exynos_drm_rotator.o 24 23 exynosdrm-$(CONFIG_DRM_EXYNOS_GSC) += exynos_drm_gsc.o 24 + exynosdrm-$(CONFIG_DRM_EXYNOS_MIC) += exynos_drm_mic.o 25 25 26 26 obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
+660
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
··· 1 + /* drivers/gpu/drm/exynos5433_drm_decon.c 2 + * 3 + * Copyright (C) 2015 Samsung Electronics Co.Ltd 4 + * Authors: 5 + * Joonyoung Shim <jy0922.shim@samsung.com> 6 + * Hyungwon Hwang <human.hwang@samsung.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundationr 11 + */ 12 + 13 + #include <linux/platform_device.h> 14 + #include <linux/clk.h> 15 + #include <linux/component.h> 16 + #include <linux/of_gpio.h> 17 + #include <linux/pm_runtime.h> 18 + 19 + #include <video/exynos5433_decon.h> 20 + 21 + #include "exynos_drm_drv.h" 22 + #include "exynos_drm_crtc.h" 23 + #include "exynos_drm_plane.h" 24 + #include "exynos_drm_iommu.h" 25 + 26 + #define WINDOWS_NR 3 27 + #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 28 + 29 + struct decon_context { 30 + struct device *dev; 31 + struct drm_device *drm_dev; 32 + struct exynos_drm_crtc *crtc; 33 + struct exynos_drm_plane planes[WINDOWS_NR]; 34 + void __iomem *addr; 35 + struct clk *clks[6]; 36 + unsigned int default_win; 37 + unsigned long irq_flags; 38 + int pipe; 39 + bool suspended; 40 + 41 + #define BIT_CLKS_ENABLED 0 42 + #define BIT_IRQS_ENABLED 1 43 + unsigned long enabled; 44 + bool i80_if; 45 + atomic_t win_updated; 46 + }; 47 + 48 + static const char * const decon_clks_name[] = { 49 + "aclk_decon", 50 + "aclk_smmu_decon0x", 51 + "aclk_xiu_decon0x", 52 + "pclk_smmu_decon0x", 53 + "sclk_decon_vclk", 54 + "sclk_decon_eclk", 55 + }; 56 + 57 + static int decon_enable_vblank(struct exynos_drm_crtc *crtc) 58 + { 59 + struct decon_context *ctx = crtc->ctx; 60 + u32 val; 61 + 62 + if (ctx->suspended) 63 + return -EPERM; 64 + 65 + if (test_and_set_bit(0, &ctx->irq_flags)) { 66 + val = VIDINTCON0_INTEN; 67 + if (ctx->i80_if) 68 + val |= VIDINTCON0_FRAMEDONE; 69 + else 70 + val |= VIDINTCON0_INTFRMEN; 71 + 72 + writel(val, ctx->addr + DECON_VIDINTCON0); 73 + } 74 + 75 + return 0; 76 + } 77 + 78 + static void decon_disable_vblank(struct exynos_drm_crtc *crtc) 79 + { 80 + struct decon_context *ctx = crtc->ctx; 81 + 82 + if (ctx->suspended) 83 + return; 84 + 85 + if (test_and_clear_bit(0, &ctx->irq_flags)) 86 + writel(0, ctx->addr + DECON_VIDINTCON0); 87 + } 88 + 89 + static void decon_setup_trigger(struct decon_context *ctx) 90 + { 91 + u32 val = TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | 92 + TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN; 93 + writel(val, ctx->addr + DECON_TRIGCON); 94 + } 95 + 96 + static void decon_commit(struct exynos_drm_crtc *crtc) 97 + { 98 + struct decon_context *ctx = crtc->ctx; 99 + struct drm_display_mode *mode = &crtc->base.mode; 100 + u32 val; 101 + 102 + if (ctx->suspended) 103 + return; 104 + 105 + /* enable clock gate */ 106 + val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F; 107 + writel(val, ctx->addr + DECON_CMU); 108 + 109 + /* lcd on and use command if */ 110 + val = VIDOUT_LCD_ON; 111 + if (ctx->i80_if) 112 + val |= VIDOUT_COMMAND_IF; 113 + else 114 + val |= VIDOUT_RGB_IF; 115 + writel(val, ctx->addr + DECON_VIDOUTCON0); 116 + 117 + val = VIDTCON2_LINEVAL(mode->vdisplay - 1) | 118 + VIDTCON2_HOZVAL(mode->hdisplay - 1); 119 + writel(val, ctx->addr + DECON_VIDTCON2); 120 + 121 + if (!ctx->i80_if) { 122 + val = VIDTCON00_VBPD_F( 123 + mode->crtc_vtotal - mode->crtc_vsync_end) | 124 + VIDTCON00_VFPD_F( 125 + mode->crtc_vsync_start - mode->crtc_vdisplay); 126 + writel(val, ctx->addr + DECON_VIDTCON00); 127 + 128 + val = VIDTCON01_VSPW_F( 129 + mode->crtc_vsync_end - mode->crtc_vsync_start); 130 + writel(val, ctx->addr + DECON_VIDTCON01); 131 + 132 + val = VIDTCON10_HBPD_F( 133 + mode->crtc_htotal - mode->crtc_hsync_end) | 134 + VIDTCON10_HFPD_F( 135 + mode->crtc_hsync_start - mode->crtc_hdisplay); 136 + writel(val, ctx->addr + DECON_VIDTCON10); 137 + 138 + val = VIDTCON11_HSPW_F( 139 + mode->crtc_hsync_end - mode->crtc_hsync_start); 140 + writel(val, ctx->addr + DECON_VIDTCON11); 141 + } 142 + 143 + decon_setup_trigger(ctx); 144 + 145 + /* enable output and display signal */ 146 + val = VIDCON0_ENVID | VIDCON0_ENVID_F; 147 + writel(val, ctx->addr + DECON_VIDCON0); 148 + } 149 + 150 + #define COORDINATE_X(x) (((x) & 0xfff) << 12) 151 + #define COORDINATE_Y(x) ((x) & 0xfff) 152 + #define OFFSIZE(x) (((x) & 0x3fff) << 14) 153 + #define PAGEWIDTH(x) ((x) & 0x3fff) 154 + 155 + static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) 156 + { 157 + struct exynos_drm_plane *plane = &ctx->planes[win]; 158 + unsigned long val; 159 + 160 + val = readl(ctx->addr + DECON_WINCONx(win)); 161 + val &= ~WINCONx_BPPMODE_MASK; 162 + 163 + switch (plane->pixel_format) { 164 + case DRM_FORMAT_XRGB1555: 165 + val |= WINCONx_BPPMODE_16BPP_I1555; 166 + val |= WINCONx_HAWSWP_F; 167 + val |= WINCONx_BURSTLEN_16WORD; 168 + break; 169 + case DRM_FORMAT_RGB565: 170 + val |= WINCONx_BPPMODE_16BPP_565; 171 + val |= WINCONx_HAWSWP_F; 172 + val |= WINCONx_BURSTLEN_16WORD; 173 + break; 174 + case DRM_FORMAT_XRGB8888: 175 + val |= WINCONx_BPPMODE_24BPP_888; 176 + val |= WINCONx_WSWP_F; 177 + val |= WINCONx_BURSTLEN_16WORD; 178 + break; 179 + case DRM_FORMAT_ARGB8888: 180 + val |= WINCONx_BPPMODE_32BPP_A8888; 181 + val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F; 182 + val |= WINCONx_BURSTLEN_16WORD; 183 + break; 184 + default: 185 + DRM_ERROR("Proper pixel format is not set\n"); 186 + return; 187 + } 188 + 189 + DRM_DEBUG_KMS("bpp = %u\n", plane->bpp); 190 + 191 + /* 192 + * In case of exynos, setting dma-burst to 16Word causes permanent 193 + * tearing for very small buffers, e.g. cursor buffer. Burst Mode 194 + * switching which is based on plane size is not recommended as 195 + * plane size varies a lot towards the end of the screen and rapid 196 + * movement causes unstable DMA which results into iommu crash/tear. 197 + */ 198 + 199 + if (plane->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) { 200 + val &= ~WINCONx_BURSTLEN_MASK; 201 + val |= WINCONx_BURSTLEN_8WORD; 202 + } 203 + 204 + writel(val, ctx->addr + DECON_WINCONx(win)); 205 + } 206 + 207 + static void decon_shadow_protect_win(struct decon_context *ctx, int win, 208 + bool protect) 209 + { 210 + u32 val; 211 + 212 + val = readl(ctx->addr + DECON_SHADOWCON); 213 + 214 + if (protect) 215 + val |= SHADOWCON_Wx_PROTECT(win); 216 + else 217 + val &= ~SHADOWCON_Wx_PROTECT(win); 218 + 219 + writel(val, ctx->addr + DECON_SHADOWCON); 220 + } 221 + 222 + static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win) 223 + { 224 + struct decon_context *ctx = crtc->ctx; 225 + struct exynos_drm_plane *plane; 226 + u32 val; 227 + 228 + if (win < 0 || win >= WINDOWS_NR) 229 + return; 230 + 231 + plane = &ctx->planes[win]; 232 + 233 + if (ctx->suspended) 234 + return; 235 + 236 + decon_shadow_protect_win(ctx, win, true); 237 + 238 + val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y); 239 + writel(val, ctx->addr + DECON_VIDOSDxA(win)); 240 + 241 + val = COORDINATE_X(plane->crtc_x + plane->crtc_width - 1) | 242 + COORDINATE_Y(plane->crtc_y + plane->crtc_height - 1); 243 + writel(val, ctx->addr + DECON_VIDOSDxB(win)); 244 + 245 + val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | 246 + VIDOSD_Wx_ALPHA_B_F(0x0); 247 + writel(val, ctx->addr + DECON_VIDOSDxC(win)); 248 + 249 + val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | 250 + VIDOSD_Wx_ALPHA_B_F(0x0); 251 + writel(val, ctx->addr + DECON_VIDOSDxD(win)); 252 + 253 + writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win)); 254 + 255 + val = plane->dma_addr[0] + plane->pitch * plane->crtc_height; 256 + writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); 257 + 258 + val = OFFSIZE(plane->pitch - plane->crtc_width * (plane->bpp >> 3)) 259 + | PAGEWIDTH(plane->crtc_width * (plane->bpp >> 3)); 260 + writel(val, ctx->addr + DECON_VIDW0xADD2(win)); 261 + 262 + decon_win_set_pixfmt(ctx, win); 263 + 264 + /* window enable */ 265 + val = readl(ctx->addr + DECON_WINCONx(win)); 266 + val |= WINCONx_ENWIN_F; 267 + writel(val, ctx->addr + DECON_WINCONx(win)); 268 + 269 + decon_shadow_protect_win(ctx, win, false); 270 + 271 + /* standalone update */ 272 + val = readl(ctx->addr + DECON_UPDATE); 273 + val |= STANDALONE_UPDATE_F; 274 + writel(val, ctx->addr + DECON_UPDATE); 275 + 276 + if (ctx->i80_if) 277 + atomic_set(&ctx->win_updated, 1); 278 + } 279 + 280 + static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) 281 + { 282 + struct decon_context *ctx = crtc->ctx; 283 + struct exynos_drm_plane *plane; 284 + u32 val; 285 + 286 + if (win < 0 || win >= WINDOWS_NR) 287 + return; 288 + 289 + plane = &ctx->planes[win]; 290 + 291 + if (ctx->suspended) 292 + return; 293 + 294 + decon_shadow_protect_win(ctx, win, true); 295 + 296 + /* window disable */ 297 + val = readl(ctx->addr + DECON_WINCONx(win)); 298 + val &= ~WINCONx_ENWIN_F; 299 + writel(val, ctx->addr + DECON_WINCONx(win)); 300 + 301 + decon_shadow_protect_win(ctx, win, false); 302 + 303 + /* standalone update */ 304 + val = readl(ctx->addr + DECON_UPDATE); 305 + val |= STANDALONE_UPDATE_F; 306 + writel(val, ctx->addr + DECON_UPDATE); 307 + } 308 + 309 + static void decon_swreset(struct decon_context *ctx) 310 + { 311 + unsigned int tries; 312 + 313 + writel(0, ctx->addr + DECON_VIDCON0); 314 + for (tries = 2000; tries; --tries) { 315 + if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS) 316 + break; 317 + udelay(10); 318 + } 319 + 320 + WARN(tries == 0, "failed to disable DECON\n"); 321 + 322 + writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0); 323 + for (tries = 2000; tries; --tries) { 324 + if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET) 325 + break; 326 + udelay(10); 327 + } 328 + 329 + WARN(tries == 0, "failed to software reset DECON\n"); 330 + } 331 + 332 + static void decon_enable(struct exynos_drm_crtc *crtc) 333 + { 334 + struct decon_context *ctx = crtc->ctx; 335 + int ret; 336 + int i; 337 + 338 + if (!ctx->suspended) 339 + return; 340 + 341 + ctx->suspended = false; 342 + 343 + pm_runtime_get_sync(ctx->dev); 344 + 345 + for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 346 + ret = clk_prepare_enable(ctx->clks[i]); 347 + if (ret < 0) 348 + goto err; 349 + } 350 + 351 + set_bit(BIT_CLKS_ENABLED, &ctx->enabled); 352 + 353 + /* if vblank was enabled status, enable it again. */ 354 + if (test_and_clear_bit(0, &ctx->irq_flags)) 355 + decon_enable_vblank(ctx->crtc); 356 + 357 + decon_commit(ctx->crtc); 358 + 359 + return; 360 + err: 361 + while (--i >= 0) 362 + clk_disable_unprepare(ctx->clks[i]); 363 + 364 + ctx->suspended = true; 365 + } 366 + 367 + static void decon_disable(struct exynos_drm_crtc *crtc) 368 + { 369 + struct decon_context *ctx = crtc->ctx; 370 + int i; 371 + 372 + if (ctx->suspended) 373 + return; 374 + 375 + /* 376 + * We need to make sure that all windows are disabled before we 377 + * suspend that connector. Otherwise we might try to scan from 378 + * a destroyed buffer later. 379 + */ 380 + for (i = 0; i < WINDOWS_NR; i++) 381 + decon_win_disable(crtc, i); 382 + 383 + decon_swreset(ctx); 384 + 385 + for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) 386 + clk_disable_unprepare(ctx->clks[i]); 387 + 388 + clear_bit(BIT_CLKS_ENABLED, &ctx->enabled); 389 + 390 + pm_runtime_put_sync(ctx->dev); 391 + 392 + ctx->suspended = true; 393 + } 394 + 395 + void decon_te_irq_handler(struct exynos_drm_crtc *crtc) 396 + { 397 + struct decon_context *ctx = crtc->ctx; 398 + u32 val; 399 + 400 + if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled)) 401 + return; 402 + 403 + if (atomic_add_unless(&ctx->win_updated, -1, 0)) { 404 + /* trigger */ 405 + val = readl(ctx->addr + DECON_TRIGCON); 406 + val |= TRIGCON_SWTRIGCMD; 407 + writel(val, ctx->addr + DECON_TRIGCON); 408 + } 409 + 410 + drm_handle_vblank(ctx->drm_dev, ctx->pipe); 411 + } 412 + 413 + static void decon_clear_channels(struct exynos_drm_crtc *crtc) 414 + { 415 + struct decon_context *ctx = crtc->ctx; 416 + int win, i, ret; 417 + u32 val; 418 + 419 + DRM_DEBUG_KMS("%s\n", __FILE__); 420 + 421 + for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 422 + ret = clk_prepare_enable(ctx->clks[i]); 423 + if (ret < 0) 424 + goto err; 425 + } 426 + 427 + for (win = 0; win < WINDOWS_NR; win++) { 428 + /* shadow update disable */ 429 + val = readl(ctx->addr + DECON_SHADOWCON); 430 + val |= SHADOWCON_Wx_PROTECT(win); 431 + writel(val, ctx->addr + DECON_SHADOWCON); 432 + 433 + /* window disable */ 434 + val = readl(ctx->addr + DECON_WINCONx(win)); 435 + val &= ~WINCONx_ENWIN_F; 436 + writel(val, ctx->addr + DECON_WINCONx(win)); 437 + 438 + /* shadow update enable */ 439 + val = readl(ctx->addr + DECON_SHADOWCON); 440 + val &= ~SHADOWCON_Wx_PROTECT(win); 441 + writel(val, ctx->addr + DECON_SHADOWCON); 442 + 443 + /* standalone update */ 444 + val = readl(ctx->addr + DECON_UPDATE); 445 + val |= STANDALONE_UPDATE_F; 446 + writel(val, ctx->addr + DECON_UPDATE); 447 + } 448 + /* TODO: wait for possible vsync */ 449 + msleep(50); 450 + 451 + err: 452 + while (--i >= 0) 453 + clk_disable_unprepare(ctx->clks[i]); 454 + } 455 + 456 + static struct exynos_drm_crtc_ops decon_crtc_ops = { 457 + .enable = decon_enable, 458 + .disable = decon_disable, 459 + .commit = decon_commit, 460 + .enable_vblank = decon_enable_vblank, 461 + .disable_vblank = decon_disable_vblank, 462 + .commit = decon_commit, 463 + .win_commit = decon_win_commit, 464 + .win_disable = decon_win_disable, 465 + .te_handler = decon_te_irq_handler, 466 + .clear_channels = decon_clear_channels, 467 + }; 468 + 469 + static int decon_bind(struct device *dev, struct device *master, void *data) 470 + { 471 + struct decon_context *ctx = dev_get_drvdata(dev); 472 + struct drm_device *drm_dev = data; 473 + struct exynos_drm_private *priv = drm_dev->dev_private; 474 + struct exynos_drm_plane *exynos_plane; 475 + enum drm_plane_type type; 476 + unsigned int zpos; 477 + int ret; 478 + 479 + ctx->drm_dev = drm_dev; 480 + ctx->pipe = priv->pipe++; 481 + 482 + for (zpos = 0; zpos < WINDOWS_NR; zpos++) { 483 + type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY : 484 + DRM_PLANE_TYPE_OVERLAY; 485 + ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], 486 + 1 << ctx->pipe, type, zpos); 487 + if (ret) 488 + return ret; 489 + } 490 + 491 + exynos_plane = &ctx->planes[ctx->default_win]; 492 + ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, 493 + ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD, 494 + &decon_crtc_ops, ctx); 495 + if (IS_ERR(ctx->crtc)) { 496 + ret = PTR_ERR(ctx->crtc); 497 + goto err; 498 + } 499 + 500 + ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev); 501 + if (ret) 502 + goto err; 503 + 504 + return ret; 505 + err: 506 + priv->pipe--; 507 + return ret; 508 + } 509 + 510 + static void decon_unbind(struct device *dev, struct device *master, void *data) 511 + { 512 + struct decon_context *ctx = dev_get_drvdata(dev); 513 + 514 + decon_disable(ctx->crtc); 515 + 516 + /* detach this sub driver from iommu mapping if supported. */ 517 + if (is_drm_iommu_supported(ctx->drm_dev)) 518 + drm_iommu_detach_device(ctx->drm_dev, ctx->dev); 519 + } 520 + 521 + static const struct component_ops decon_component_ops = { 522 + .bind = decon_bind, 523 + .unbind = decon_unbind, 524 + }; 525 + 526 + static irqreturn_t decon_vsync_irq_handler(int irq, void *dev_id) 527 + { 528 + struct decon_context *ctx = dev_id; 529 + u32 val; 530 + 531 + if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled)) 532 + goto out; 533 + 534 + val = readl(ctx->addr + DECON_VIDINTCON1); 535 + if (val & VIDINTCON1_INTFRMPEND) { 536 + drm_handle_vblank(ctx->drm_dev, ctx->pipe); 537 + 538 + /* clear */ 539 + writel(VIDINTCON1_INTFRMPEND, ctx->addr + DECON_VIDINTCON1); 540 + } 541 + 542 + out: 543 + return IRQ_HANDLED; 544 + } 545 + 546 + static irqreturn_t decon_lcd_sys_irq_handler(int irq, void *dev_id) 547 + { 548 + struct decon_context *ctx = dev_id; 549 + u32 val; 550 + 551 + if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled)) 552 + goto out; 553 + 554 + val = readl(ctx->addr + DECON_VIDINTCON1); 555 + if (val & VIDINTCON1_INTFRMDONEPEND) { 556 + exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); 557 + 558 + /* clear */ 559 + writel(VIDINTCON1_INTFRMDONEPEND, 560 + ctx->addr + DECON_VIDINTCON1); 561 + } 562 + 563 + out: 564 + return IRQ_HANDLED; 565 + } 566 + 567 + static int exynos5433_decon_probe(struct platform_device *pdev) 568 + { 569 + struct device *dev = &pdev->dev; 570 + struct decon_context *ctx; 571 + struct resource *res; 572 + int ret; 573 + int i; 574 + 575 + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 576 + if (!ctx) 577 + return -ENOMEM; 578 + 579 + ctx->default_win = 0; 580 + ctx->suspended = true; 581 + ctx->dev = dev; 582 + if (of_get_child_by_name(dev->of_node, "i80-if-timings")) 583 + ctx->i80_if = true; 584 + 585 + for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 586 + struct clk *clk; 587 + 588 + clk = devm_clk_get(ctx->dev, decon_clks_name[i]); 589 + if (IS_ERR(clk)) 590 + return PTR_ERR(clk); 591 + 592 + ctx->clks[i] = clk; 593 + } 594 + 595 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 596 + if (!res) { 597 + dev_err(dev, "cannot find IO resource\n"); 598 + return -ENXIO; 599 + } 600 + 601 + ctx->addr = devm_ioremap_resource(dev, res); 602 + if (IS_ERR(ctx->addr)) { 603 + dev_err(dev, "ioremap failed\n"); 604 + return PTR_ERR(ctx->addr); 605 + } 606 + 607 + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 608 + ctx->i80_if ? "lcd_sys" : "vsync"); 609 + if (!res) { 610 + dev_err(dev, "cannot find IRQ resource\n"); 611 + return -ENXIO; 612 + } 613 + 614 + ret = devm_request_irq(dev, res->start, ctx->i80_if ? 615 + decon_lcd_sys_irq_handler : decon_vsync_irq_handler, 0, 616 + "drm_decon", ctx); 617 + if (ret < 0) { 618 + dev_err(dev, "lcd_sys irq request failed\n"); 619 + return ret; 620 + } 621 + 622 + platform_set_drvdata(pdev, ctx); 623 + 624 + pm_runtime_enable(dev); 625 + 626 + ret = component_add(dev, &decon_component_ops); 627 + if (ret) 628 + goto err_disable_pm_runtime; 629 + 630 + return 0; 631 + 632 + err_disable_pm_runtime: 633 + pm_runtime_disable(dev); 634 + 635 + return ret; 636 + } 637 + 638 + static int exynos5433_decon_remove(struct platform_device *pdev) 639 + { 640 + pm_runtime_disable(&pdev->dev); 641 + 642 + component_del(&pdev->dev, &decon_component_ops); 643 + 644 + return 0; 645 + } 646 + 647 + static const struct of_device_id exynos5433_decon_driver_dt_match[] = { 648 + { .compatible = "samsung,exynos5433-decon" }, 649 + {}, 650 + }; 651 + MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match); 652 + 653 + struct platform_driver exynos5433_decon_driver = { 654 + .probe = exynos5433_decon_probe, 655 + .remove = exynos5433_decon_remove, 656 + .driver = { 657 + .name = "exynos5433-decon", 658 + .of_match_table = exynos5433_decon_driver_dt_match, 659 + }, 660 + };
+34 -139
drivers/gpu/drm/exynos/exynos7_drm_decon.c
··· 89 89 DRM_DEBUG_KMS("vblank wait timed out.\n"); 90 90 } 91 91 92 - static void decon_clear_channel(struct decon_context *ctx) 92 + static void decon_clear_channels(struct exynos_drm_crtc *crtc) 93 93 { 94 + struct decon_context *ctx = crtc->ctx; 94 95 unsigned int win, ch_enabled = 0; 95 96 96 97 DRM_DEBUG_KMS("%s\n", __FILE__); ··· 121 120 struct drm_device *drm_dev) 122 121 { 123 122 struct exynos_drm_private *priv = drm_dev->dev_private; 123 + int ret; 124 124 125 125 ctx->drm_dev = drm_dev; 126 126 ctx->pipe = priv->pipe++; 127 127 128 - /* attach this sub driver to iommu mapping if supported. */ 129 - if (is_drm_iommu_supported(ctx->drm_dev)) { 130 - int ret; 128 + ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, ctx->dev); 129 + if (ret) 130 + priv->pipe--; 131 131 132 - /* 133 - * If any channel is already active, iommu will throw 134 - * a PAGE FAULT when enabled. So clear any channel if enabled. 135 - */ 136 - decon_clear_channel(ctx); 137 - ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev); 138 - if (ret) { 139 - DRM_ERROR("drm_iommu_attach failed.\n"); 140 - return ret; 141 - } 142 - } 143 - 144 - return 0; 132 + return ret; 145 133 } 146 134 147 135 static void decon_ctx_remove(struct decon_context *ctx) ··· 165 175 static void decon_commit(struct exynos_drm_crtc *crtc) 166 176 { 167 177 struct decon_context *ctx = crtc->ctx; 168 - struct drm_display_mode *mode = &crtc->base.mode; 178 + struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; 169 179 u32 val, clkdiv; 170 180 171 181 if (ctx->suspended) ··· 385 395 static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win) 386 396 { 387 397 struct decon_context *ctx = crtc->ctx; 388 - struct drm_display_mode *mode = &crtc->base.mode; 398 + struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; 389 399 struct exynos_drm_plane *plane; 390 400 int padding; 391 401 unsigned long val, alpha; ··· 400 410 401 411 plane = &ctx->planes[win]; 402 412 403 - /* If suspended, enable this on resume */ 404 - if (ctx->suspended) { 405 - plane->resume = true; 413 + if (ctx->suspended) 406 414 return; 407 - } 408 415 409 416 /* 410 417 * SHADOWCON/PRTCON register is used for enabling timing. ··· 493 506 val = readl(ctx->regs + DECON_UPDATE); 494 507 val |= DECON_UPDATE_STANDALONE_F; 495 508 writel(val, ctx->regs + DECON_UPDATE); 496 - 497 - plane->enabled = true; 498 509 } 499 510 500 511 static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) ··· 506 521 507 522 plane = &ctx->planes[win]; 508 523 509 - if (ctx->suspended) { 510 - /* do not resume this window*/ 511 - plane->resume = false; 524 + if (ctx->suspended) 512 525 return; 513 - } 514 526 515 527 /* protect windows */ 516 528 decon_shadow_protect_win(ctx, win, true); ··· 523 541 val = readl(ctx->regs + DECON_UPDATE); 524 542 val |= DECON_UPDATE_STANDALONE_F; 525 543 writel(val, ctx->regs + DECON_UPDATE); 526 - 527 - plane->enabled = false; 528 - } 529 - 530 - static void decon_window_suspend(struct decon_context *ctx) 531 - { 532 - struct exynos_drm_plane *plane; 533 - int i; 534 - 535 - for (i = 0; i < WINDOWS_NR; i++) { 536 - plane = &ctx->planes[i]; 537 - plane->resume = plane->enabled; 538 - if (plane->enabled) 539 - decon_win_disable(ctx->crtc, i); 540 - } 541 - } 542 - 543 - static void decon_window_resume(struct decon_context *ctx) 544 - { 545 - struct exynos_drm_plane *plane; 546 - int i; 547 - 548 - for (i = 0; i < WINDOWS_NR; i++) { 549 - plane = &ctx->planes[i]; 550 - plane->enabled = plane->resume; 551 - plane->resume = false; 552 - } 553 - } 554 - 555 - static void decon_apply(struct decon_context *ctx) 556 - { 557 - struct exynos_drm_plane *plane; 558 - int i; 559 - 560 - for (i = 0; i < WINDOWS_NR; i++) { 561 - plane = &ctx->planes[i]; 562 - if (plane->enabled) 563 - decon_win_commit(ctx->crtc, i); 564 - else 565 - decon_win_disable(ctx->crtc, i); 566 - } 567 - 568 - decon_commit(ctx->crtc); 569 544 } 570 545 571 546 static void decon_init(struct decon_context *ctx) ··· 542 603 writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0)); 543 604 } 544 605 545 - static int decon_poweron(struct decon_context *ctx) 606 + static void decon_enable(struct exynos_drm_crtc *crtc) 546 607 { 608 + struct decon_context *ctx = crtc->ctx; 547 609 int ret; 548 610 549 611 if (!ctx->suspended) 550 - return 0; 612 + return; 551 613 552 614 ctx->suspended = false; 553 615 ··· 557 617 ret = clk_prepare_enable(ctx->pclk); 558 618 if (ret < 0) { 559 619 DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret); 560 - goto pclk_err; 620 + return; 561 621 } 562 622 563 623 ret = clk_prepare_enable(ctx->aclk); 564 624 if (ret < 0) { 565 625 DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret); 566 - goto aclk_err; 626 + return; 567 627 } 568 628 569 629 ret = clk_prepare_enable(ctx->eclk); 570 630 if (ret < 0) { 571 631 DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret); 572 - goto eclk_err; 632 + return; 573 633 } 574 634 575 635 ret = clk_prepare_enable(ctx->vclk); 576 636 if (ret < 0) { 577 637 DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret); 578 - goto vclk_err; 638 + return; 579 639 } 580 640 581 641 decon_init(ctx); 582 642 583 643 /* if vblank was enabled status, enable it again. */ 584 - if (test_and_clear_bit(0, &ctx->irq_flags)) { 585 - ret = decon_enable_vblank(ctx->crtc); 586 - if (ret) { 587 - DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); 588 - goto err; 589 - } 590 - } 644 + if (test_and_clear_bit(0, &ctx->irq_flags)) 645 + decon_enable_vblank(ctx->crtc); 591 646 592 - decon_window_resume(ctx); 593 - 594 - decon_apply(ctx); 595 - 596 - return 0; 597 - 598 - err: 599 - clk_disable_unprepare(ctx->vclk); 600 - vclk_err: 601 - clk_disable_unprepare(ctx->eclk); 602 - eclk_err: 603 - clk_disable_unprepare(ctx->aclk); 604 - aclk_err: 605 - clk_disable_unprepare(ctx->pclk); 606 - pclk_err: 607 - ctx->suspended = true; 608 - return ret; 647 + decon_commit(ctx->crtc); 609 648 } 610 649 611 - static int decon_poweroff(struct decon_context *ctx) 650 + static void decon_disable(struct exynos_drm_crtc *crtc) 612 651 { 652 + struct decon_context *ctx = crtc->ctx; 653 + int i; 654 + 613 655 if (ctx->suspended) 614 - return 0; 656 + return; 615 657 616 658 /* 617 659 * We need to make sure that all windows are disabled before we 618 660 * suspend that connector. Otherwise we might try to scan from 619 661 * a destroyed buffer later. 620 662 */ 621 - decon_window_suspend(ctx); 663 + for (i = 0; i < WINDOWS_NR; i++) 664 + decon_win_disable(crtc, i); 622 665 623 666 clk_disable_unprepare(ctx->vclk); 624 667 clk_disable_unprepare(ctx->eclk); ··· 611 688 pm_runtime_put_sync(ctx->dev); 612 689 613 690 ctx->suspended = true; 614 - return 0; 615 - } 616 - 617 - static void decon_dpms(struct exynos_drm_crtc *crtc, int mode) 618 - { 619 - DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); 620 - 621 - switch (mode) { 622 - case DRM_MODE_DPMS_ON: 623 - decon_poweron(crtc->ctx); 624 - break; 625 - case DRM_MODE_DPMS_STANDBY: 626 - case DRM_MODE_DPMS_SUSPEND: 627 - case DRM_MODE_DPMS_OFF: 628 - decon_poweroff(crtc->ctx); 629 - break; 630 - default: 631 - DRM_DEBUG_KMS("unspecified mode %d\n", mode); 632 - break; 633 - } 634 691 } 635 692 636 693 static const struct exynos_drm_crtc_ops decon_crtc_ops = { 637 - .dpms = decon_dpms, 694 + .enable = decon_enable, 695 + .disable = decon_disable, 638 696 .mode_fixup = decon_mode_fixup, 639 697 .commit = decon_commit, 640 698 .enable_vblank = decon_enable_vblank, ··· 623 719 .wait_for_vblank = decon_wait_for_vblank, 624 720 .win_commit = decon_win_commit, 625 721 .win_disable = decon_win_disable, 722 + .clear_channels = decon_clear_channels, 626 723 }; 627 724 628 725 ··· 701 796 { 702 797 struct decon_context *ctx = dev_get_drvdata(dev); 703 798 704 - decon_dpms(ctx->crtc, DRM_MODE_DPMS_OFF); 799 + decon_disable(ctx->crtc); 705 800 706 801 if (ctx->display) 707 802 exynos_dpi_remove(ctx->display); ··· 729 824 if (!ctx) 730 825 return -ENOMEM; 731 826 732 - ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, 733 - EXYNOS_DISPLAY_TYPE_LCD); 734 - if (ret) 735 - return ret; 736 - 737 827 ctx->dev = dev; 738 828 ctx->suspended = true; 739 829 ··· 738 838 of_node_put(i80_if_timings); 739 839 740 840 ctx->regs = of_iomap(dev->of_node, 0); 741 - if (!ctx->regs) { 742 - ret = -ENOMEM; 743 - goto err_del_component; 744 - } 841 + if (!ctx->regs) 842 + return -ENOMEM; 745 843 746 844 ctx->pclk = devm_clk_get(dev, "pclk_decon0"); 747 845 if (IS_ERR(ctx->pclk)) { ··· 809 911 err_iounmap: 810 912 iounmap(ctx->regs); 811 913 812 - err_del_component: 813 - exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC); 814 914 return ret; 815 915 } 816 916 ··· 821 925 iounmap(ctx->regs); 822 926 823 927 component_del(&pdev->dev, &decon_component_ops); 824 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 825 928 826 929 return 0; 827 930 }
+6 -14
drivers/gpu/drm/exynos/exynos_dp_core.c
··· 28 28 #include <drm/drmP.h> 29 29 #include <drm/drm_crtc.h> 30 30 #include <drm/drm_crtc_helper.h> 31 + #include <drm/drm_atomic_helper.h> 31 32 #include <drm/drm_panel.h> 32 33 33 34 #include "exynos_dp_core.h" ··· 953 952 } 954 953 955 954 static struct drm_connector_funcs exynos_dp_connector_funcs = { 956 - .dpms = drm_helper_connector_dpms, 955 + .dpms = drm_atomic_helper_connector_dpms, 957 956 .fill_modes = drm_helper_probe_single_connector_modes, 958 957 .detect = exynos_dp_detect, 959 958 .destroy = exynos_dp_connector_destroy, 959 + .reset = drm_atomic_helper_connector_reset, 960 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 961 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 960 962 }; 961 963 962 964 static int exynos_dp_get_modes(struct drm_connector *connector) ··· 1332 1328 struct device *dev = &pdev->dev; 1333 1329 struct device_node *panel_node, *bridge_node, *endpoint; 1334 1330 struct exynos_dp_device *dp; 1335 - int ret; 1336 1331 1337 1332 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 1338 1333 GFP_KERNEL); ··· 1341 1338 dp->display.type = EXYNOS_DISPLAY_TYPE_LCD; 1342 1339 dp->display.ops = &exynos_dp_display_ops; 1343 1340 platform_set_drvdata(pdev, dp); 1344 - 1345 - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, 1346 - dp->display.type); 1347 - if (ret) 1348 - return ret; 1349 1341 1350 1342 panel_node = of_parse_phandle(dev->of_node, "panel", 0); 1351 1343 if (panel_node) { ··· 1362 1364 return -EPROBE_DEFER; 1363 1365 } 1364 1366 1365 - ret = component_add(&pdev->dev, &exynos_dp_ops); 1366 - if (ret) 1367 - exynos_drm_component_del(&pdev->dev, 1368 - EXYNOS_DEVICE_TYPE_CONNECTOR); 1369 - 1370 - return ret; 1367 + return component_add(&pdev->dev, &exynos_dp_ops); 1371 1368 } 1372 1369 1373 1370 static int exynos_dp_remove(struct platform_device *pdev) 1374 1371 { 1375 1372 component_del(&pdev->dev, &exynos_dp_ops); 1376 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 1377 1373 1378 1374 return 0; 1379 1375 }
+46 -161
drivers/gpu/drm/exynos/exynos_drm_crtc.c
··· 14 14 15 15 #include <drm/drmP.h> 16 16 #include <drm/drm_crtc_helper.h> 17 + #include <drm/drm_atomic.h> 18 + #include <drm/drm_atomic_helper.h> 17 19 18 20 #include "exynos_drm_crtc.h" 19 21 #include "exynos_drm_drv.h" 20 22 #include "exynos_drm_encoder.h" 21 23 #include "exynos_drm_plane.h" 22 24 23 - static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) 25 + static void exynos_drm_crtc_enable(struct drm_crtc *crtc) 24 26 { 25 27 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 26 28 27 - DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); 28 - 29 - if (exynos_crtc->dpms == mode) { 30 - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); 29 + if (exynos_crtc->enabled) 31 30 return; 32 - } 33 31 34 - if (mode > DRM_MODE_DPMS_ON) { 35 - /* wait for the completion of page flip. */ 36 - if (!wait_event_timeout(exynos_crtc->pending_flip_queue, 37 - (exynos_crtc->event == NULL), HZ/20)) 38 - exynos_crtc->event = NULL; 39 - drm_crtc_vblank_off(crtc); 40 - } 32 + if (exynos_crtc->ops->enable) 33 + exynos_crtc->ops->enable(exynos_crtc); 41 34 42 - if (exynos_crtc->ops->dpms) 43 - exynos_crtc->ops->dpms(exynos_crtc, mode); 35 + exynos_crtc->enabled = true; 44 36 45 - exynos_crtc->dpms = mode; 46 - 47 - if (mode == DRM_MODE_DPMS_ON) 48 - drm_crtc_vblank_on(crtc); 37 + drm_crtc_vblank_on(crtc); 49 38 } 50 39 51 - static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) 52 - { 53 - /* drm framework doesn't check NULL. */ 54 - } 55 - 56 - static void exynos_drm_crtc_commit(struct drm_crtc *crtc) 40 + static void exynos_drm_crtc_disable(struct drm_crtc *crtc) 57 41 { 58 42 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 59 - struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary); 60 43 61 - exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 44 + if (!exynos_crtc->enabled) 45 + return; 62 46 63 - if (exynos_crtc->ops->win_commit) 64 - exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); 47 + /* wait for the completion of page flip. */ 48 + if (!wait_event_timeout(exynos_crtc->pending_flip_queue, 49 + (exynos_crtc->event == NULL), HZ/20)) 50 + exynos_crtc->event = NULL; 65 51 66 - if (exynos_crtc->ops->commit) 67 - exynos_crtc->ops->commit(exynos_crtc); 52 + drm_crtc_vblank_off(crtc); 53 + 54 + if (exynos_crtc->ops->disable) 55 + exynos_crtc->ops->disable(exynos_crtc); 56 + 57 + exynos_crtc->enabled = false; 68 58 } 69 59 70 60 static bool ··· 71 81 return true; 72 82 } 73 83 74 - static int 75 - exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 76 - struct drm_display_mode *adjusted_mode, int x, int y, 77 - struct drm_framebuffer *old_fb) 78 - { 79 - struct drm_framebuffer *fb = crtc->primary->fb; 80 - unsigned int crtc_w; 81 - unsigned int crtc_h; 82 - int ret; 83 - 84 - /* 85 - * copy the mode data adjusted by mode_fixup() into crtc->mode 86 - * so that hardware can be seet to proper mode. 87 - */ 88 - memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); 89 - 90 - ret = exynos_check_plane(crtc->primary, fb); 91 - if (ret < 0) 92 - return ret; 93 - 94 - crtc_w = fb->width - x; 95 - crtc_h = fb->height - y; 96 - exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0, 97 - crtc_w, crtc_h, x, y, crtc_w, crtc_h); 98 - 99 - return 0; 100 - } 101 - 102 - static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 103 - struct drm_framebuffer *old_fb) 84 + static void 85 + exynos_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) 104 86 { 105 87 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 106 - struct drm_framebuffer *fb = crtc->primary->fb; 107 - unsigned int crtc_w; 108 - unsigned int crtc_h; 109 88 110 - /* when framebuffer changing is requested, crtc's dpms should be on */ 111 - if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { 112 - DRM_ERROR("failed framebuffer changing request.\n"); 113 - return -EPERM; 114 - } 115 - 116 - crtc_w = fb->width - x; 117 - crtc_h = fb->height - y; 118 - 119 - return exynos_update_plane(crtc->primary, crtc, fb, 0, 0, 120 - crtc_w, crtc_h, x, y, crtc_w, crtc_h); 89 + if (exynos_crtc->ops->commit) 90 + exynos_crtc->ops->commit(exynos_crtc); 121 91 } 122 92 123 - static void exynos_drm_crtc_disable(struct drm_crtc *crtc) 93 + static void exynos_crtc_atomic_begin(struct drm_crtc *crtc) 124 94 { 125 - struct drm_plane *plane; 126 - int ret; 95 + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 127 96 128 - exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 129 - 130 - drm_for_each_legacy_plane(plane, &crtc->dev->mode_config.plane_list) { 131 - if (plane->crtc != crtc) 132 - continue; 133 - 134 - ret = plane->funcs->disable_plane(plane); 135 - if (ret) 136 - DRM_ERROR("Failed to disable plane %d\n", ret); 97 + if (crtc->state->event) { 98 + WARN_ON(drm_crtc_vblank_get(crtc) != 0); 99 + exynos_crtc->event = crtc->state->event; 137 100 } 101 + } 102 + 103 + static void exynos_crtc_atomic_flush(struct drm_crtc *crtc) 104 + { 138 105 } 139 106 140 107 static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { 141 - .dpms = exynos_drm_crtc_dpms, 142 - .prepare = exynos_drm_crtc_prepare, 143 - .commit = exynos_drm_crtc_commit, 144 - .mode_fixup = exynos_drm_crtc_mode_fixup, 145 - .mode_set = exynos_drm_crtc_mode_set, 146 - .mode_set_base = exynos_drm_crtc_mode_set_base, 108 + .enable = exynos_drm_crtc_enable, 147 109 .disable = exynos_drm_crtc_disable, 110 + .mode_fixup = exynos_drm_crtc_mode_fixup, 111 + .mode_set_nofb = exynos_drm_crtc_mode_set_nofb, 112 + .atomic_begin = exynos_crtc_atomic_begin, 113 + .atomic_flush = exynos_crtc_atomic_flush, 148 114 }; 149 - 150 - static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, 151 - struct drm_framebuffer *fb, 152 - struct drm_pending_vblank_event *event, 153 - uint32_t page_flip_flags) 154 - { 155 - struct drm_device *dev = crtc->dev; 156 - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 157 - struct drm_framebuffer *old_fb = crtc->primary->fb; 158 - unsigned int crtc_w, crtc_h; 159 - int ret; 160 - 161 - /* when the page flip is requested, crtc's dpms should be on */ 162 - if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { 163 - DRM_ERROR("failed page flip request.\n"); 164 - return -EINVAL; 165 - } 166 - 167 - if (!event) 168 - return -EINVAL; 169 - 170 - spin_lock_irq(&dev->event_lock); 171 - if (exynos_crtc->event) { 172 - ret = -EBUSY; 173 - goto out; 174 - } 175 - 176 - ret = drm_vblank_get(dev, exynos_crtc->pipe); 177 - if (ret) { 178 - DRM_DEBUG("failed to acquire vblank counter\n"); 179 - goto out; 180 - } 181 - 182 - exynos_crtc->event = event; 183 - spin_unlock_irq(&dev->event_lock); 184 - 185 - /* 186 - * the pipe from user always is 0 so we can set pipe number 187 - * of current owner to event. 188 - */ 189 - event->pipe = exynos_crtc->pipe; 190 - 191 - crtc->primary->fb = fb; 192 - crtc_w = fb->width - crtc->x; 193 - crtc_h = fb->height - crtc->y; 194 - ret = exynos_update_plane(crtc->primary, crtc, fb, 0, 0, 195 - crtc_w, crtc_h, crtc->x, crtc->y, 196 - crtc_w, crtc_h); 197 - if (ret) { 198 - crtc->primary->fb = old_fb; 199 - spin_lock_irq(&dev->event_lock); 200 - exynos_crtc->event = NULL; 201 - drm_vblank_put(dev, exynos_crtc->pipe); 202 - spin_unlock_irq(&dev->event_lock); 203 - return ret; 204 - } 205 - 206 - return 0; 207 - 208 - out: 209 - spin_unlock_irq(&dev->event_lock); 210 - return ret; 211 - } 212 115 213 116 static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) 214 117 { ··· 115 232 } 116 233 117 234 static struct drm_crtc_funcs exynos_crtc_funcs = { 118 - .set_config = drm_crtc_helper_set_config, 119 - .page_flip = exynos_drm_crtc_page_flip, 235 + .set_config = drm_atomic_helper_set_config, 236 + .page_flip = drm_atomic_helper_page_flip, 120 237 .destroy = exynos_drm_crtc_destroy, 238 + .reset = drm_atomic_helper_crtc_reset, 239 + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 240 + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 121 241 }; 122 242 123 243 struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, ··· 141 255 142 256 init_waitqueue_head(&exynos_crtc->pending_flip_queue); 143 257 144 - exynos_crtc->dpms = DRM_MODE_DPMS_OFF; 145 258 exynos_crtc->pipe = pipe; 146 259 exynos_crtc->type = type; 147 260 exynos_crtc->ops = ops; ··· 171 286 struct exynos_drm_crtc *exynos_crtc = 172 287 to_exynos_crtc(private->crtc[pipe]); 173 288 174 - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) 289 + if (!exynos_crtc->enabled) 175 290 return -EPERM; 176 291 177 292 if (exynos_crtc->ops->enable_vblank) ··· 186 301 struct exynos_drm_crtc *exynos_crtc = 187 302 to_exynos_crtc(private->crtc[pipe]); 188 303 189 - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) 304 + if (!exynos_crtc->enabled) 190 305 return; 191 306 192 307 if (exynos_crtc->ops->disable_vblank)
+7 -19
drivers/gpu/drm/exynos/exynos_drm_dpi.c
··· 13 13 #include <drm/drmP.h> 14 14 #include <drm/drm_crtc_helper.h> 15 15 #include <drm/drm_panel.h> 16 + #include <drm/drm_atomic_helper.h> 16 17 17 18 #include <linux/regulator/consumer.h> 18 19 ··· 60 59 } 61 60 62 61 static struct drm_connector_funcs exynos_dpi_connector_funcs = { 63 - .dpms = drm_helper_connector_dpms, 62 + .dpms = drm_atomic_helper_connector_dpms, 64 63 .detect = exynos_dpi_detect, 65 64 .fill_modes = drm_helper_probe_single_connector_modes, 66 65 .destroy = exynos_dpi_connector_destroy, 66 + .reset = drm_atomic_helper_connector_reset, 67 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 68 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 67 69 }; 68 70 69 71 static int exynos_dpi_get_modes(struct drm_connector *connector) ··· 313 309 ctx->dev = dev; 314 310 ctx->dpms_mode = DRM_MODE_DPMS_OFF; 315 311 316 - ret = exynos_drm_component_add(dev, 317 - EXYNOS_DEVICE_TYPE_CONNECTOR, 318 - ctx->display.type); 319 - if (ret) 320 - return ERR_PTR(ret); 321 - 322 312 ret = exynos_dpi_parse_dt(ctx); 323 313 if (ret < 0) { 324 314 devm_kfree(dev, ctx); 325 - goto err_del_component; 315 + return NULL; 326 316 } 327 317 328 318 if (ctx->panel_node) { 329 319 ctx->panel = of_drm_find_panel(ctx->panel_node); 330 - if (!ctx->panel) { 331 - exynos_drm_component_del(dev, 332 - EXYNOS_DEVICE_TYPE_CONNECTOR); 320 + if (!ctx->panel) 333 321 return ERR_PTR(-EPROBE_DEFER); 334 - } 335 322 } 336 323 337 324 return &ctx->display; 338 - 339 - err_del_component: 340 - exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 341 - 342 - return NULL; 343 325 } 344 326 345 327 int exynos_dpi_remove(struct exynos_drm_display *display) ··· 336 346 337 347 if (ctx->panel) 338 348 drm_panel_detach(ctx->panel); 339 - 340 - exynos_drm_component_del(ctx->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 341 349 342 350 return 0; 343 351 }
+175 -278
drivers/gpu/drm/exynos/exynos_drm_drv.c
··· 38 38 #define DRIVER_MAJOR 1 39 39 #define DRIVER_MINOR 0 40 40 41 - static struct platform_device *exynos_drm_pdev; 42 - 43 - static DEFINE_MUTEX(drm_component_lock); 44 - static LIST_HEAD(drm_component_list); 45 - 46 - struct component_dev { 47 - struct list_head list; 48 - struct device *crtc_dev; 49 - struct device *conn_dev; 50 - enum exynos_drm_output_type out_type; 51 - unsigned int dev_type_flag; 52 - }; 53 - 54 41 static int exynos_drm_load(struct drm_device *dev, unsigned long flags) 55 42 { 56 43 struct exynos_drm_private *private; ··· 84 97 ret = exynos_drm_device_subdrv_probe(dev); 85 98 if (ret) 86 99 goto err_cleanup_vblank; 100 + 101 + drm_mode_config_reset(dev); 87 102 88 103 /* 89 104 * enable drm irq mode. ··· 337 348 SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume) 338 349 }; 339 350 340 - int exynos_drm_component_add(struct device *dev, 341 - enum exynos_drm_device_type dev_type, 342 - enum exynos_drm_output_type out_type) 343 - { 344 - struct component_dev *cdev; 351 + /* forward declaration */ 352 + static struct platform_driver exynos_drm_platform_driver; 345 353 346 - if (dev_type != EXYNOS_DEVICE_TYPE_CRTC && 347 - dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) { 348 - DRM_ERROR("invalid device type.\n"); 349 - return -EINVAL; 350 - } 351 - 352 - mutex_lock(&drm_component_lock); 353 - 354 - /* 355 - * Make sure to check if there is a component which has two device 356 - * objects, for connector and for encoder/connector. 357 - * It should make sure that crtc and encoder/connector drivers are 358 - * ready before exynos drm core binds them. 359 - */ 360 - list_for_each_entry(cdev, &drm_component_list, list) { 361 - if (cdev->out_type == out_type) { 362 - /* 363 - * If crtc and encoder/connector device objects are 364 - * added already just return. 365 - */ 366 - if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC | 367 - EXYNOS_DEVICE_TYPE_CONNECTOR)) { 368 - mutex_unlock(&drm_component_lock); 369 - return 0; 370 - } 371 - 372 - if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) { 373 - cdev->crtc_dev = dev; 374 - cdev->dev_type_flag |= dev_type; 375 - } 376 - 377 - if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) { 378 - cdev->conn_dev = dev; 379 - cdev->dev_type_flag |= dev_type; 380 - } 381 - 382 - mutex_unlock(&drm_component_lock); 383 - return 0; 384 - } 385 - } 386 - 387 - mutex_unlock(&drm_component_lock); 388 - 389 - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 390 - if (!cdev) 391 - return -ENOMEM; 392 - 393 - if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) 394 - cdev->crtc_dev = dev; 395 - if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) 396 - cdev->conn_dev = dev; 397 - 398 - cdev->out_type = out_type; 399 - cdev->dev_type_flag = dev_type; 400 - 401 - mutex_lock(&drm_component_lock); 402 - list_add_tail(&cdev->list, &drm_component_list); 403 - mutex_unlock(&drm_component_lock); 404 - 405 - return 0; 406 - } 407 - 408 - void exynos_drm_component_del(struct device *dev, 409 - enum exynos_drm_device_type dev_type) 410 - { 411 - struct component_dev *cdev, *next; 412 - 413 - mutex_lock(&drm_component_lock); 414 - 415 - list_for_each_entry_safe(cdev, next, &drm_component_list, list) { 416 - if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) { 417 - if (cdev->crtc_dev == dev) { 418 - cdev->crtc_dev = NULL; 419 - cdev->dev_type_flag &= ~dev_type; 420 - } 421 - } 422 - 423 - if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) { 424 - if (cdev->conn_dev == dev) { 425 - cdev->conn_dev = NULL; 426 - cdev->dev_type_flag &= ~dev_type; 427 - } 428 - } 429 - 430 - /* 431 - * Release cdev object only in case that both of crtc and 432 - * encoder/connector device objects are NULL. 433 - */ 434 - if (!cdev->crtc_dev && !cdev->conn_dev) { 435 - list_del(&cdev->list); 436 - kfree(cdev); 437 - } 438 - } 439 - 440 - mutex_unlock(&drm_component_lock); 441 - } 442 - 443 - static int compare_dev(struct device *dev, void *data) 444 - { 445 - return dev == (struct device *)data; 446 - } 447 - 448 - static struct component_match *exynos_drm_match_add(struct device *dev) 449 - { 450 - struct component_match *match = NULL; 451 - struct component_dev *cdev; 452 - unsigned int attach_cnt = 0; 453 - 454 - mutex_lock(&drm_component_lock); 455 - 456 - /* Do not retry to probe if there is no any kms driver regitered. */ 457 - if (list_empty(&drm_component_list)) { 458 - mutex_unlock(&drm_component_lock); 459 - return ERR_PTR(-ENODEV); 460 - } 461 - 462 - list_for_each_entry(cdev, &drm_component_list, list) { 463 - /* 464 - * Add components to master only in case that crtc and 465 - * encoder/connector device objects exist. 466 - */ 467 - if (!cdev->crtc_dev || !cdev->conn_dev) 468 - continue; 469 - 470 - attach_cnt++; 471 - 472 - mutex_unlock(&drm_component_lock); 473 - 474 - /* 475 - * fimd and dpi modules have same device object so add 476 - * only crtc device object in this case. 477 - */ 478 - if (cdev->crtc_dev == cdev->conn_dev) { 479 - component_match_add(dev, &match, compare_dev, 480 - cdev->crtc_dev); 481 - goto out_lock; 482 - } 483 - 484 - /* 485 - * Do not chage below call order. 486 - * crtc device first should be added to master because 487 - * connector/encoder need pipe number of crtc when they 488 - * are created. 489 - */ 490 - component_match_add(dev, &match, compare_dev, cdev->crtc_dev); 491 - component_match_add(dev, &match, compare_dev, cdev->conn_dev); 492 - 493 - out_lock: 494 - mutex_lock(&drm_component_lock); 495 - } 496 - 497 - mutex_unlock(&drm_component_lock); 498 - 499 - return attach_cnt ? match : ERR_PTR(-EPROBE_DEFER); 500 - } 501 - 502 - static int exynos_drm_bind(struct device *dev) 503 - { 504 - return drm_platform_init(&exynos_drm_driver, to_platform_device(dev)); 505 - } 506 - 507 - static void exynos_drm_unbind(struct device *dev) 508 - { 509 - drm_put_dev(dev_get_drvdata(dev)); 510 - } 511 - 512 - static const struct component_master_ops exynos_drm_ops = { 513 - .bind = exynos_drm_bind, 514 - .unbind = exynos_drm_unbind, 515 - }; 516 - 354 + /* 355 + * Connector drivers should not be placed before associated crtc drivers, 356 + * because connector requires pipe number of its crtc during initialization. 357 + */ 517 358 static struct platform_driver *const exynos_drm_kms_drivers[] = { 359 + #ifdef CONFIG_DRM_EXYNOS_VIDI 360 + &vidi_driver, 361 + #endif 518 362 #ifdef CONFIG_DRM_EXYNOS_FIMD 519 363 &fimd_driver, 520 364 #endif 365 + #ifdef CONFIG_DRM_EXYNOS5433_DECON 366 + &exynos5433_decon_driver, 367 + #endif 521 368 #ifdef CONFIG_DRM_EXYNOS7_DECON 522 369 &decon_driver, 370 + #endif 371 + #ifdef CONFIG_DRM_EXYNOS_MIC 372 + &mic_driver, 523 373 #endif 524 374 #ifdef CONFIG_DRM_EXYNOS_DP 525 375 &dp_driver, ··· 388 560 #ifdef CONFIG_DRM_EXYNOS_IPP 389 561 &ipp_driver, 390 562 #endif 563 + &exynos_drm_platform_driver, 564 + }; 565 + 566 + static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = { 567 + #ifdef CONFIG_DRM_EXYNOS_VIDI 568 + &vidi_driver, 569 + #endif 570 + #ifdef CONFIG_DRM_EXYNOS_IPP 571 + &ipp_driver, 572 + #endif 573 + &exynos_drm_platform_driver, 574 + }; 575 + #define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev) 576 + 577 + static int compare_dev(struct device *dev, void *data) 578 + { 579 + return dev == (struct device *)data; 580 + } 581 + 582 + static struct component_match *exynos_drm_match_add(struct device *dev) 583 + { 584 + struct component_match *match = NULL; 585 + int i; 586 + 587 + for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) { 588 + struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver; 589 + struct device *p = NULL, *d; 590 + 591 + while ((d = bus_find_device(&platform_bus_type, p, drv, 592 + (void *)platform_bus_type.match))) { 593 + put_device(p); 594 + component_match_add(dev, &match, compare_dev, d); 595 + p = d; 596 + } 597 + put_device(p); 598 + } 599 + 600 + return match ?: ERR_PTR(-ENODEV); 601 + } 602 + 603 + static int exynos_drm_bind(struct device *dev) 604 + { 605 + return drm_platform_init(&exynos_drm_driver, to_platform_device(dev)); 606 + } 607 + 608 + static void exynos_drm_unbind(struct device *dev) 609 + { 610 + drm_put_dev(dev_get_drvdata(dev)); 611 + } 612 + 613 + static const struct component_master_ops exynos_drm_ops = { 614 + .bind = exynos_drm_bind, 615 + .unbind = exynos_drm_unbind, 391 616 }; 392 617 393 618 static int exynos_drm_platform_probe(struct platform_device *pdev) ··· 451 570 exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls); 452 571 453 572 match = exynos_drm_match_add(&pdev->dev); 454 - if (IS_ERR(match)) { 573 + if (IS_ERR(match)) 455 574 return PTR_ERR(match); 456 - } 457 575 458 576 return component_master_add_with_match(&pdev->dev, &exynos_drm_ops, 459 577 match); ··· 464 584 return 0; 465 585 } 466 586 467 - static const char * const strings[] = { 468 - "samsung,exynos3", 469 - "samsung,exynos4", 470 - "samsung,exynos5", 471 - "samsung,exynos7", 472 - }; 473 - 474 587 static struct platform_driver exynos_drm_platform_driver = { 475 588 .probe = exynos_drm_platform_probe, 476 589 .remove = exynos_drm_platform_remove, ··· 473 600 }, 474 601 }; 475 602 603 + static struct platform_device *exynos_drm_pdevs[PDEV_COUNT]; 604 + 605 + static void exynos_drm_unregister_devices(void) 606 + { 607 + int i = PDEV_COUNT; 608 + 609 + while (--i >= 0) { 610 + platform_device_unregister(exynos_drm_pdevs[i]); 611 + exynos_drm_pdevs[i] = NULL; 612 + } 613 + } 614 + 615 + static int exynos_drm_register_devices(void) 616 + { 617 + int i; 618 + 619 + for (i = 0; i < PDEV_COUNT; ++i) { 620 + struct platform_driver *d = exynos_drm_drv_with_simple_dev[i]; 621 + struct platform_device *pdev = 622 + platform_device_register_simple(d->driver.name, -1, 623 + NULL, 0); 624 + 625 + if (!IS_ERR(pdev)) { 626 + exynos_drm_pdevs[i] = pdev; 627 + continue; 628 + } 629 + while (--i >= 0) { 630 + platform_device_unregister(exynos_drm_pdevs[i]); 631 + exynos_drm_pdevs[i] = NULL; 632 + } 633 + 634 + return PTR_ERR(pdev); 635 + } 636 + 637 + return 0; 638 + } 639 + 640 + static void exynos_drm_unregister_drivers(struct platform_driver * const *drv, 641 + int count) 642 + { 643 + while (--count >= 0) 644 + platform_driver_unregister(drv[count]); 645 + } 646 + 647 + static int exynos_drm_register_drivers(struct platform_driver * const *drv, 648 + int count) 649 + { 650 + int i, ret; 651 + 652 + for (i = 0; i < count; ++i) { 653 + ret = platform_driver_register(drv[i]); 654 + if (!ret) 655 + continue; 656 + 657 + while (--i >= 0) 658 + platform_driver_unregister(drv[i]); 659 + 660 + return ret; 661 + } 662 + 663 + return 0; 664 + } 665 + 666 + static inline int exynos_drm_register_kms_drivers(void) 667 + { 668 + return exynos_drm_register_drivers(exynos_drm_kms_drivers, 669 + ARRAY_SIZE(exynos_drm_kms_drivers)); 670 + } 671 + 672 + static inline int exynos_drm_register_non_kms_drivers(void) 673 + { 674 + return exynos_drm_register_drivers(exynos_drm_non_kms_drivers, 675 + ARRAY_SIZE(exynos_drm_non_kms_drivers)); 676 + } 677 + 678 + static inline void exynos_drm_unregister_kms_drivers(void) 679 + { 680 + exynos_drm_unregister_drivers(exynos_drm_kms_drivers, 681 + ARRAY_SIZE(exynos_drm_kms_drivers)); 682 + } 683 + 684 + static inline void exynos_drm_unregister_non_kms_drivers(void) 685 + { 686 + exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers, 687 + ARRAY_SIZE(exynos_drm_non_kms_drivers)); 688 + } 689 + 476 690 static int exynos_drm_init(void) 477 691 { 478 - bool is_exynos = false; 479 - int ret, i, j; 692 + int ret; 480 693 481 - /* 482 - * Register device object only in case of Exynos SoC. 483 - * 484 - * Below codes resolves temporarily infinite loop issue incurred 485 - * by Exynos drm driver when using multi-platform kernel. 486 - * So these codes will be replaced with more generic way later. 487 - */ 488 - for (i = 0; i < ARRAY_SIZE(strings); i++) { 489 - if (of_machine_is_compatible(strings[i])) { 490 - is_exynos = true; 491 - break; 492 - } 493 - } 494 - 495 - if (!is_exynos) 496 - return -ENODEV; 497 - 498 - exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, 499 - NULL, 0); 500 - if (IS_ERR(exynos_drm_pdev)) 501 - return PTR_ERR(exynos_drm_pdev); 502 - 503 - ret = exynos_drm_probe_vidi(); 504 - if (ret < 0) 505 - goto err_unregister_pd; 506 - 507 - for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) { 508 - ret = platform_driver_register(exynos_drm_kms_drivers[i]); 509 - if (ret < 0) 510 - goto err_unregister_kms_drivers; 511 - } 512 - 513 - for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) { 514 - ret = platform_driver_register(exynos_drm_non_kms_drivers[j]); 515 - if (ret < 0) 516 - goto err_unregister_non_kms_drivers; 517 - } 518 - 519 - #ifdef CONFIG_DRM_EXYNOS_IPP 520 - ret = exynos_platform_device_ipp_register(); 521 - if (ret < 0) 522 - goto err_unregister_non_kms_drivers; 523 - #endif 524 - 525 - ret = platform_driver_register(&exynos_drm_platform_driver); 694 + ret = exynos_drm_register_devices(); 526 695 if (ret) 527 - goto err_unregister_resources; 696 + return ret; 697 + 698 + ret = exynos_drm_register_kms_drivers(); 699 + if (ret) 700 + goto err_unregister_pdevs; 701 + 702 + ret = exynos_drm_register_non_kms_drivers(); 703 + if (ret) 704 + goto err_unregister_kms_drivers; 528 705 529 706 return 0; 530 707 531 - err_unregister_resources: 532 - #ifdef CONFIG_DRM_EXYNOS_IPP 533 - exynos_platform_device_ipp_unregister(); 534 - #endif 535 - 536 - err_unregister_non_kms_drivers: 537 - while (--j >= 0) 538 - platform_driver_unregister(exynos_drm_non_kms_drivers[j]); 539 - 540 708 err_unregister_kms_drivers: 541 - while (--i >= 0) 542 - platform_driver_unregister(exynos_drm_kms_drivers[i]); 709 + exynos_drm_unregister_kms_drivers(); 543 710 544 - exynos_drm_remove_vidi(); 545 - 546 - err_unregister_pd: 547 - platform_device_unregister(exynos_drm_pdev); 711 + err_unregister_pdevs: 712 + exynos_drm_unregister_devices(); 548 713 549 714 return ret; 550 715 } 551 716 552 717 static void exynos_drm_exit(void) 553 718 { 554 - int i; 555 - 556 - #ifdef CONFIG_DRM_EXYNOS_IPP 557 - exynos_platform_device_ipp_unregister(); 558 - #endif 559 - 560 - for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i) 561 - platform_driver_unregister(exynos_drm_non_kms_drivers[i]); 562 - 563 - for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i) 564 - platform_driver_unregister(exynos_drm_kms_drivers[i]); 565 - 566 - platform_driver_unregister(&exynos_drm_platform_driver); 567 - 568 - exynos_drm_remove_vidi(); 569 - 570 - platform_device_unregister(exynos_drm_pdev); 719 + exynos_drm_unregister_non_kms_drivers(); 720 + exynos_drm_unregister_kms_drivers(); 721 + exynos_drm_unregister_devices(); 571 722 } 572 723 573 724 module_init(exynos_drm_init);
+9 -40
drivers/gpu/drm/exynos/exynos_drm_drv.h
··· 25 25 #define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base) 26 26 #define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base) 27 27 28 - /* This enumerates device type. */ 29 - enum exynos_drm_device_type { 30 - EXYNOS_DEVICE_TYPE_NONE, 31 - EXYNOS_DEVICE_TYPE_CRTC, 32 - EXYNOS_DEVICE_TYPE_CONNECTOR, 33 - }; 34 - 35 28 /* this enumerates display type. */ 36 29 enum exynos_drm_output_type { 37 30 EXYNOS_DISPLAY_TYPE_NONE, ··· 64 71 * @dma_addr: array of bus(accessed by dma) address to the memory region 65 72 * allocated for a overlay. 66 73 * @zpos: order of overlay layer(z position). 67 - * @enabled: enabled or not. 68 - * @resume: to resume or not. 69 74 * 70 75 * this structure is common to exynos SoC and its contents would be copied 71 76 * to hardware specific overlay info. ··· 92 101 uint32_t pixel_format; 93 102 dma_addr_t dma_addr[MAX_FB_BUFFER]; 94 103 unsigned int zpos; 95 - 96 - bool enabled:1; 97 - bool resume:1; 98 104 }; 99 105 100 106 /* ··· 145 157 /* 146 158 * Exynos drm crtc ops 147 159 * 148 - * @dpms: control device power. 160 + * @enable: enable the device 161 + * @disable: disable the device 149 162 * @mode_fixup: fix mode data before applying it 150 163 * @commit: set current hw specific display mode to hw. 151 164 * @enable_vblank: specific driver callback for enabling vblank interrupt. ··· 164 175 */ 165 176 struct exynos_drm_crtc; 166 177 struct exynos_drm_crtc_ops { 167 - void (*dpms)(struct exynos_drm_crtc *crtc, int mode); 178 + void (*enable)(struct exynos_drm_crtc *crtc); 179 + void (*disable)(struct exynos_drm_crtc *crtc); 168 180 bool (*mode_fixup)(struct exynos_drm_crtc *crtc, 169 181 const struct drm_display_mode *mode, 170 182 struct drm_display_mode *adjusted_mode); ··· 177 187 void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos); 178 188 void (*te_handler)(struct exynos_drm_crtc *crtc); 179 189 void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); 190 + void (*clear_channels)(struct exynos_drm_crtc *crtc); 180 191 }; 181 192 182 193 /* ··· 192 201 * drm framework doesn't support multiple irq yet. 193 202 * we can refer to the crtc to current hardware interrupt occurred through 194 203 * this pipe value. 195 - * @dpms: store the crtc dpms value 204 + * @enabled: if the crtc is enabled or not 196 205 * @event: vblank event that is currently queued for flip 197 206 * @ops: pointer to callbacks for exynos drm specific functionality 198 207 * @ctx: A pointer to the crtc's implementation specific context ··· 201 210 struct drm_crtc base; 202 211 enum exynos_drm_output_type type; 203 212 unsigned int pipe; 204 - unsigned int dpms; 213 + bool enabled; 205 214 wait_queue_head_t pending_flip_queue; 206 215 struct drm_pending_vblank_event *event; 207 216 const struct exynos_drm_crtc_ops *ops; ··· 284 293 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); 285 294 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); 286 295 287 - #ifdef CONFIG_DRM_EXYNOS_IPP 288 - int exynos_platform_device_ipp_register(void); 289 - void exynos_platform_device_ipp_unregister(void); 290 - #else 291 - static inline int exynos_platform_device_ipp_register(void) { return 0; } 292 - static inline void exynos_platform_device_ipp_unregister(void) {} 293 - #endif 294 - 295 - 296 296 #ifdef CONFIG_DRM_EXYNOS_DPI 297 297 struct exynos_drm_display * exynos_dpi_probe(struct device *dev); 298 298 int exynos_dpi_remove(struct exynos_drm_display *display); ··· 296 314 } 297 315 #endif 298 316 299 - #ifdef CONFIG_DRM_EXYNOS_VIDI 300 - int exynos_drm_probe_vidi(void); 301 - void exynos_drm_remove_vidi(void); 302 - #else 303 - static inline int exynos_drm_probe_vidi(void) { return 0; } 304 - static inline void exynos_drm_remove_vidi(void) {} 305 - #endif 306 - 307 317 /* This function creates a encoder and a connector, and initializes them. */ 308 318 int exynos_drm_create_enc_conn(struct drm_device *dev, 309 319 struct exynos_drm_display *display); 310 320 311 - int exynos_drm_component_add(struct device *dev, 312 - enum exynos_drm_device_type dev_type, 313 - enum exynos_drm_output_type out_type); 314 - 315 - void exynos_drm_component_del(struct device *dev, 316 - enum exynos_drm_device_type dev_type); 317 - 318 321 extern struct platform_driver fimd_driver; 322 + extern struct platform_driver exynos5433_decon_driver; 319 323 extern struct platform_driver decon_driver; 320 324 extern struct platform_driver dp_driver; 321 325 extern struct platform_driver dsi_driver; ··· 314 346 extern struct platform_driver rotator_driver; 315 347 extern struct platform_driver gsc_driver; 316 348 extern struct platform_driver ipp_driver; 349 + extern struct platform_driver mic_driver; 317 350 #endif
+360 -179
drivers/gpu/drm/exynos/exynos_drm_dsi.c
··· 14 14 #include <drm/drm_crtc_helper.h> 15 15 #include <drm/drm_mipi_dsi.h> 16 16 #include <drm/drm_panel.h> 17 + #include <drm/drm_atomic_helper.h> 17 18 18 19 #include <linux/clk.h> 19 20 #include <linux/gpio/consumer.h> 20 21 #include <linux/irq.h> 21 22 #include <linux/of_device.h> 22 23 #include <linux/of_gpio.h> 24 + #include <linux/of_graph.h> 23 25 #include <linux/phy/phy.h> 24 26 #include <linux/regulator/consumer.h> 25 27 #include <linux/component.h> ··· 34 32 35 33 /* returns true iff both arguments logically differs */ 36 34 #define NEQV(a, b) (!(a) ^ !(b)) 37 - 38 - #define DSIM_STATUS_REG 0x0 /* Status register */ 39 - #define DSIM_SWRST_REG 0x4 /* Software reset register */ 40 - #define DSIM_CLKCTRL_REG 0x8 /* Clock control register */ 41 - #define DSIM_TIMEOUT_REG 0xc /* Time out register */ 42 - #define DSIM_CONFIG_REG 0x10 /* Configuration register */ 43 - #define DSIM_ESCMODE_REG 0x14 /* Escape mode register */ 44 - 45 - /* Main display image resolution register */ 46 - #define DSIM_MDRESOL_REG 0x18 47 - #define DSIM_MVPORCH_REG 0x1c /* Main display Vporch register */ 48 - #define DSIM_MHPORCH_REG 0x20 /* Main display Hporch register */ 49 - #define DSIM_MSYNC_REG 0x24 /* Main display sync area register */ 50 - 51 - /* Sub display image resolution register */ 52 - #define DSIM_SDRESOL_REG 0x28 53 - #define DSIM_INTSRC_REG 0x2c /* Interrupt source register */ 54 - #define DSIM_INTMSK_REG 0x30 /* Interrupt mask register */ 55 - #define DSIM_PKTHDR_REG 0x34 /* Packet Header FIFO register */ 56 - #define DSIM_PAYLOAD_REG 0x38 /* Payload FIFO register */ 57 - #define DSIM_RXFIFO_REG 0x3c /* Read FIFO register */ 58 - #define DSIM_FIFOTHLD_REG 0x40 /* FIFO threshold level register */ 59 - #define DSIM_FIFOCTRL_REG 0x44 /* FIFO status and control register */ 60 - 61 - /* FIFO memory AC characteristic register */ 62 - #define DSIM_PLLCTRL_REG 0x4c /* PLL control register */ 63 - #define DSIM_PHYACCHR_REG 0x54 /* D-PHY AC characteristic register */ 64 - #define DSIM_PHYACCHR1_REG 0x58 /* D-PHY AC characteristic register1 */ 65 - #define DSIM_PHYCTRL_REG 0x5c 66 - #define DSIM_PHYTIMING_REG 0x64 67 - #define DSIM_PHYTIMING1_REG 0x68 68 - #define DSIM_PHYTIMING2_REG 0x6c 69 35 70 36 /* DSIM_STATUS */ 71 37 #define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0) ··· 98 128 99 129 /* DSIM_MDRESOL */ 100 130 #define DSIM_MAIN_STAND_BY (1 << 31) 101 - #define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16) 102 - #define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0) 131 + #define DSIM_MAIN_VRESOL(x, num_bits) (((x) & ((1 << (num_bits)) - 1)) << 16) 132 + #define DSIM_MAIN_HRESOL(x, num_bits) (((x) & ((1 << (num_bits)) - 1)) << 0) 103 133 104 134 /* DSIM_MVPORCH */ 105 135 #define DSIM_CMD_ALLOW(x) ((x) << 28) ··· 133 163 #define DSIM_INT_PLL_STABLE (1 << 31) 134 164 #define DSIM_INT_SW_RST_RELEASE (1 << 30) 135 165 #define DSIM_INT_SFR_FIFO_EMPTY (1 << 29) 166 + #define DSIM_INT_SFR_HDR_FIFO_EMPTY (1 << 28) 136 167 #define DSIM_INT_BTA (1 << 25) 137 168 #define DSIM_INT_FRAME_DONE (1 << 24) 138 169 #define DSIM_INT_RX_TIMEOUT (1 << 21) ··· 182 211 183 212 /* DSIM_PHYCTRL */ 184 213 #define DSIM_PHYCTRL_ULPS_EXIT(x) (((x) & 0x1ff) << 0) 214 + #define DSIM_PHYCTRL_B_DPHYCTL_VREG_LP (1 << 30) 215 + #define DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP (1 << 14) 185 216 186 217 /* DSIM_PHYTIMING */ 187 218 #define DSIM_PHYTIMING_LPX(x) ((x) << 8) ··· 206 233 #define DSI_RX_FIFO_SIZE 256 207 234 #define DSI_XFER_TIMEOUT_MS 100 208 235 #define DSI_RX_FIFO_EMPTY 0x30800002 236 + 237 + #define OLD_SCLK_MIPI_CLK_NAME "pll_clk" 238 + 239 + #define REG_ADDR(dsi, reg_idx) ((dsi)->reg_base + \ 240 + dsi->driver_data->reg_ofs[(reg_idx)]) 241 + #define DSI_WRITE(dsi, reg_idx, val) writel((val), \ 242 + REG_ADDR((dsi), (reg_idx))) 243 + #define DSI_READ(dsi, reg_idx) readl(REG_ADDR((dsi), (reg_idx))) 244 + 245 + static char *clk_names[5] = { "bus_clk", "sclk_mipi", 246 + "phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0", 247 + "sclk_rgb_vclk_to_dsim0" }; 209 248 210 249 enum exynos_dsi_transfer_type { 211 250 EXYNOS_DSI_TX, ··· 244 259 #define DSIM_STATE_ENABLED BIT(0) 245 260 #define DSIM_STATE_INITIALIZED BIT(1) 246 261 #define DSIM_STATE_CMD_LPM BIT(2) 262 + #define DSIM_STATE_VIDOUT_AVAILABLE BIT(3) 247 263 248 264 struct exynos_dsi_driver_data { 265 + unsigned int *reg_ofs; 249 266 unsigned int plltmr_reg; 250 - 251 267 unsigned int has_freqband:1; 252 268 unsigned int has_clklane_stop:1; 269 + unsigned int num_clks; 270 + unsigned int max_freq; 271 + unsigned int wait_for_reset; 272 + unsigned int num_bits_resol; 273 + unsigned int *reg_values; 253 274 }; 254 275 255 276 struct exynos_dsi { ··· 268 277 269 278 void __iomem *reg_base; 270 279 struct phy *phy; 271 - struct clk *pll_clk; 272 - struct clk *bus_clk; 280 + struct clk **clks; 273 281 struct regulator_bulk_data supplies[2]; 274 282 int irq; 275 283 int te_gpio; ··· 289 299 struct list_head transfer_list; 290 300 291 301 struct exynos_dsi_driver_data *driver_data; 302 + struct device_node *bridge_node; 292 303 }; 293 304 294 305 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) ··· 300 309 return container_of(d, struct exynos_dsi, display); 301 310 } 302 311 312 + enum reg_idx { 313 + DSIM_STATUS_REG, /* Status register */ 314 + DSIM_SWRST_REG, /* Software reset register */ 315 + DSIM_CLKCTRL_REG, /* Clock control register */ 316 + DSIM_TIMEOUT_REG, /* Time out register */ 317 + DSIM_CONFIG_REG, /* Configuration register */ 318 + DSIM_ESCMODE_REG, /* Escape mode register */ 319 + DSIM_MDRESOL_REG, 320 + DSIM_MVPORCH_REG, /* Main display Vporch register */ 321 + DSIM_MHPORCH_REG, /* Main display Hporch register */ 322 + DSIM_MSYNC_REG, /* Main display sync area register */ 323 + DSIM_INTSRC_REG, /* Interrupt source register */ 324 + DSIM_INTMSK_REG, /* Interrupt mask register */ 325 + DSIM_PKTHDR_REG, /* Packet Header FIFO register */ 326 + DSIM_PAYLOAD_REG, /* Payload FIFO register */ 327 + DSIM_RXFIFO_REG, /* Read FIFO register */ 328 + DSIM_FIFOCTRL_REG, /* FIFO status and control register */ 329 + DSIM_PLLCTRL_REG, /* PLL control register */ 330 + DSIM_PHYCTRL_REG, 331 + DSIM_PHYTIMING_REG, 332 + DSIM_PHYTIMING1_REG, 333 + DSIM_PHYTIMING2_REG, 334 + NUM_REGS 335 + }; 336 + static unsigned int exynos_reg_ofs[] = { 337 + [DSIM_STATUS_REG] = 0x00, 338 + [DSIM_SWRST_REG] = 0x04, 339 + [DSIM_CLKCTRL_REG] = 0x08, 340 + [DSIM_TIMEOUT_REG] = 0x0c, 341 + [DSIM_CONFIG_REG] = 0x10, 342 + [DSIM_ESCMODE_REG] = 0x14, 343 + [DSIM_MDRESOL_REG] = 0x18, 344 + [DSIM_MVPORCH_REG] = 0x1c, 345 + [DSIM_MHPORCH_REG] = 0x20, 346 + [DSIM_MSYNC_REG] = 0x24, 347 + [DSIM_INTSRC_REG] = 0x2c, 348 + [DSIM_INTMSK_REG] = 0x30, 349 + [DSIM_PKTHDR_REG] = 0x34, 350 + [DSIM_PAYLOAD_REG] = 0x38, 351 + [DSIM_RXFIFO_REG] = 0x3c, 352 + [DSIM_FIFOCTRL_REG] = 0x44, 353 + [DSIM_PLLCTRL_REG] = 0x4c, 354 + [DSIM_PHYCTRL_REG] = 0x5c, 355 + [DSIM_PHYTIMING_REG] = 0x64, 356 + [DSIM_PHYTIMING1_REG] = 0x68, 357 + [DSIM_PHYTIMING2_REG] = 0x6c, 358 + }; 359 + 360 + static unsigned int exynos5433_reg_ofs[] = { 361 + [DSIM_STATUS_REG] = 0x04, 362 + [DSIM_SWRST_REG] = 0x0C, 363 + [DSIM_CLKCTRL_REG] = 0x10, 364 + [DSIM_TIMEOUT_REG] = 0x14, 365 + [DSIM_CONFIG_REG] = 0x18, 366 + [DSIM_ESCMODE_REG] = 0x1C, 367 + [DSIM_MDRESOL_REG] = 0x20, 368 + [DSIM_MVPORCH_REG] = 0x24, 369 + [DSIM_MHPORCH_REG] = 0x28, 370 + [DSIM_MSYNC_REG] = 0x2C, 371 + [DSIM_INTSRC_REG] = 0x34, 372 + [DSIM_INTMSK_REG] = 0x38, 373 + [DSIM_PKTHDR_REG] = 0x3C, 374 + [DSIM_PAYLOAD_REG] = 0x40, 375 + [DSIM_RXFIFO_REG] = 0x44, 376 + [DSIM_FIFOCTRL_REG] = 0x4C, 377 + [DSIM_PLLCTRL_REG] = 0x94, 378 + [DSIM_PHYCTRL_REG] = 0xA4, 379 + [DSIM_PHYTIMING_REG] = 0xB4, 380 + [DSIM_PHYTIMING1_REG] = 0xB8, 381 + [DSIM_PHYTIMING2_REG] = 0xBC, 382 + }; 383 + 384 + enum reg_value_idx { 385 + RESET_TYPE, 386 + PLL_TIMER, 387 + STOP_STATE_CNT, 388 + PHYCTRL_ULPS_EXIT, 389 + PHYCTRL_VREG_LP, 390 + PHYCTRL_SLEW_UP, 391 + PHYTIMING_LPX, 392 + PHYTIMING_HS_EXIT, 393 + PHYTIMING_CLK_PREPARE, 394 + PHYTIMING_CLK_ZERO, 395 + PHYTIMING_CLK_POST, 396 + PHYTIMING_CLK_TRAIL, 397 + PHYTIMING_HS_PREPARE, 398 + PHYTIMING_HS_ZERO, 399 + PHYTIMING_HS_TRAIL 400 + }; 401 + 402 + static unsigned int reg_values[] = { 403 + [RESET_TYPE] = DSIM_SWRST, 404 + [PLL_TIMER] = 500, 405 + [STOP_STATE_CNT] = 0xf, 406 + [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x0af), 407 + [PHYCTRL_VREG_LP] = 0, 408 + [PHYCTRL_SLEW_UP] = 0, 409 + [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06), 410 + [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b), 411 + [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07), 412 + [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x27), 413 + [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d), 414 + [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08), 415 + [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09), 416 + [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d), 417 + [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b), 418 + }; 419 + 420 + static unsigned int exynos5433_reg_values[] = { 421 + [RESET_TYPE] = DSIM_FUNCRST, 422 + [PLL_TIMER] = 22200, 423 + [STOP_STATE_CNT] = 0xa, 424 + [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x190), 425 + [PHYCTRL_VREG_LP] = DSIM_PHYCTRL_B_DPHYCTL_VREG_LP, 426 + [PHYCTRL_SLEW_UP] = DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP, 427 + [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07), 428 + [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c), 429 + [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09), 430 + [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2d), 431 + [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e), 432 + [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09), 433 + [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0b), 434 + [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x10), 435 + [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c), 436 + }; 437 + 303 438 static struct exynos_dsi_driver_data exynos3_dsi_driver_data = { 439 + .reg_ofs = exynos_reg_ofs, 304 440 .plltmr_reg = 0x50, 305 441 .has_freqband = 1, 306 442 .has_clklane_stop = 1, 443 + .num_clks = 2, 444 + .max_freq = 1000, 445 + .wait_for_reset = 1, 446 + .num_bits_resol = 11, 447 + .reg_values = reg_values, 307 448 }; 308 449 309 450 static struct exynos_dsi_driver_data exynos4_dsi_driver_data = { 451 + .reg_ofs = exynos_reg_ofs, 310 452 .plltmr_reg = 0x50, 311 453 .has_freqband = 1, 312 454 .has_clklane_stop = 1, 455 + .num_clks = 2, 456 + .max_freq = 1000, 457 + .wait_for_reset = 1, 458 + .num_bits_resol = 11, 459 + .reg_values = reg_values, 313 460 }; 314 461 315 462 static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = { 463 + .reg_ofs = exynos_reg_ofs, 316 464 .plltmr_reg = 0x58, 317 465 .has_clklane_stop = 1, 466 + .num_clks = 2, 467 + .max_freq = 1000, 468 + .wait_for_reset = 1, 469 + .num_bits_resol = 11, 470 + .reg_values = reg_values, 318 471 }; 319 472 320 473 static struct exynos_dsi_driver_data exynos5_dsi_driver_data = { 474 + .reg_ofs = exynos_reg_ofs, 321 475 .plltmr_reg = 0x58, 476 + .num_clks = 2, 477 + .max_freq = 1000, 478 + .wait_for_reset = 1, 479 + .num_bits_resol = 11, 480 + .reg_values = reg_values, 481 + }; 482 + 483 + static struct exynos_dsi_driver_data exynos5433_dsi_driver_data = { 484 + .reg_ofs = exynos5433_reg_ofs, 485 + .plltmr_reg = 0xa0, 486 + .has_clklane_stop = 1, 487 + .num_clks = 5, 488 + .max_freq = 1500, 489 + .wait_for_reset = 0, 490 + .num_bits_resol = 12, 491 + .reg_values = exynos5433_reg_values, 322 492 }; 323 493 324 494 static struct of_device_id exynos_dsi_of_match[] = { ··· 491 339 .data = &exynos4415_dsi_driver_data }, 492 340 { .compatible = "samsung,exynos5410-mipi-dsi", 493 341 .data = &exynos5_dsi_driver_data }, 342 + { .compatible = "samsung,exynos5433-mipi-dsi", 343 + .data = &exynos5433_dsi_driver_data }, 494 344 { } 495 345 }; 496 346 ··· 515 361 516 362 static void exynos_dsi_reset(struct exynos_dsi *dsi) 517 363 { 364 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 365 + 518 366 reinit_completion(&dsi->completed); 519 - writel(DSIM_SWRST, dsi->reg_base + DSIM_SWRST_REG); 367 + DSI_WRITE(dsi, DSIM_SWRST_REG, driver_data->reg_values[RESET_TYPE]); 520 368 } 521 369 522 370 #ifndef MHZ ··· 528 372 static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi, 529 373 unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s) 530 374 { 375 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 531 376 unsigned long best_freq = 0; 532 377 u32 min_delta = 0xffffffff; 533 378 u8 p_min, p_max; ··· 552 395 553 396 tmp = (u64)_m * fin; 554 397 do_div(tmp, _p); 555 - if (tmp < 500 * MHZ || tmp > 1000 * MHZ) 398 + if (tmp < 500 * MHZ || 399 + tmp > driver_data->max_freq * MHZ) 556 400 continue; 557 401 558 402 tmp = (u64)_m * fin; ··· 589 431 u16 m; 590 432 u32 reg; 591 433 592 - clk_set_rate(dsi->pll_clk, dsi->pll_clk_rate); 593 - 594 - fin = clk_get_rate(dsi->pll_clk); 595 - if (!fin) { 596 - dev_err(dsi->dev, "failed to get PLL clock frequency\n"); 597 - return 0; 598 - } 599 - 600 - dev_dbg(dsi->dev, "PLL input frequency: %lu\n", fin); 601 - 434 + fin = dsi->pll_clk_rate; 602 435 fout = exynos_dsi_pll_find_pms(dsi, fin, freq, &p, &m, &s); 603 436 if (!fout) { 604 437 dev_err(dsi->dev, ··· 598 449 } 599 450 dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s); 600 451 601 - writel(500, dsi->reg_base + driver_data->plltmr_reg); 452 + writel(driver_data->reg_values[PLL_TIMER], 453 + dsi->reg_base + driver_data->plltmr_reg); 602 454 603 455 reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s); 604 456 ··· 621 471 reg |= DSIM_FREQ_BAND(band); 622 472 } 623 473 624 - writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG); 474 + DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg); 625 475 626 476 timeout = 1000; 627 477 do { ··· 629 479 dev_err(dsi->dev, "PLL failed to stabilize\n"); 630 480 return 0; 631 481 } 632 - reg = readl(dsi->reg_base + DSIM_STATUS_REG); 482 + reg = DSI_READ(dsi, DSIM_STATUS_REG); 633 483 } while ((reg & DSIM_PLL_STABLE) == 0); 634 484 635 485 return fout; ··· 659 509 dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n", 660 510 hs_clk, byte_clk, esc_clk); 661 511 662 - reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG); 512 + reg = DSI_READ(dsi, DSIM_CLKCTRL_REG); 663 513 reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK 664 514 | DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS 665 515 | DSIM_BYTE_CLK_SRC_MASK); ··· 669 519 | DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1) 670 520 | DSIM_BYTE_CLK_SRC(0) 671 521 | DSIM_TX_REQUEST_HSCLK; 672 - writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG); 522 + DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg); 673 523 674 524 return 0; 675 525 } ··· 677 527 static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) 678 528 { 679 529 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 530 + unsigned int *reg_values = driver_data->reg_values; 680 531 u32 reg; 681 532 682 533 if (driver_data->has_freqband) 683 534 return; 684 535 685 536 /* B D-PHY: D-PHY Master & Slave Analog Block control */ 686 - reg = DSIM_PHYCTRL_ULPS_EXIT(0x0af); 687 - writel(reg, dsi->reg_base + DSIM_PHYCTRL_REG); 537 + reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] | 538 + reg_values[PHYCTRL_SLEW_UP]; 539 + DSI_WRITE(dsi, DSIM_PHYCTRL_REG, reg); 688 540 689 541 /* 690 542 * T LPX: Transmitted length of any Low-Power state period 691 543 * T HS-EXIT: Time that the transmitter drives LP-11 following a HS 692 544 * burst 693 545 */ 694 - reg = DSIM_PHYTIMING_LPX(0x06) | DSIM_PHYTIMING_HS_EXIT(0x0b); 695 - writel(reg, dsi->reg_base + DSIM_PHYTIMING_REG); 546 + reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT]; 547 + DSI_WRITE(dsi, DSIM_PHYTIMING_REG, reg); 696 548 697 549 /* 698 550 * T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00 ··· 709 557 * T CLK-TRAIL: Time that the transmitter drives the HS-0 state after 710 558 * the last payload clock bit of a HS transmission burst 711 559 */ 712 - reg = DSIM_PHYTIMING1_CLK_PREPARE(0x07) | 713 - DSIM_PHYTIMING1_CLK_ZERO(0x27) | 714 - DSIM_PHYTIMING1_CLK_POST(0x0d) | 715 - DSIM_PHYTIMING1_CLK_TRAIL(0x08); 716 - writel(reg, dsi->reg_base + DSIM_PHYTIMING1_REG); 560 + reg = reg_values[PHYTIMING_CLK_PREPARE] | 561 + reg_values[PHYTIMING_CLK_ZERO] | 562 + reg_values[PHYTIMING_CLK_POST] | 563 + reg_values[PHYTIMING_CLK_TRAIL]; 564 + 565 + DSI_WRITE(dsi, DSIM_PHYTIMING1_REG, reg); 717 566 718 567 /* 719 568 * T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00 ··· 725 572 * T HS-TRAIL: Time that the transmitter drives the flipped differential 726 573 * state after last payload data bit of a HS transmission burst 727 574 */ 728 - reg = DSIM_PHYTIMING2_HS_PREPARE(0x09) | DSIM_PHYTIMING2_HS_ZERO(0x0d) | 729 - DSIM_PHYTIMING2_HS_TRAIL(0x0b); 730 - writel(reg, dsi->reg_base + DSIM_PHYTIMING2_REG); 575 + reg = reg_values[PHYTIMING_HS_PREPARE] | reg_values[PHYTIMING_HS_ZERO] | 576 + reg_values[PHYTIMING_HS_TRAIL]; 577 + DSI_WRITE(dsi, DSIM_PHYTIMING2_REG, reg); 731 578 } 732 579 733 580 static void exynos_dsi_disable_clock(struct exynos_dsi *dsi) 734 581 { 735 582 u32 reg; 736 583 737 - reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG); 584 + reg = DSI_READ(dsi, DSIM_CLKCTRL_REG); 738 585 reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK 739 586 | DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN); 740 - writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG); 587 + DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg); 741 588 742 - reg = readl(dsi->reg_base + DSIM_PLLCTRL_REG); 589 + reg = DSI_READ(dsi, DSIM_PLLCTRL_REG); 743 590 reg &= ~DSIM_PLL_EN; 744 - writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG); 591 + DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg); 592 + } 593 + 594 + static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane) 595 + { 596 + u32 reg = DSI_READ(dsi, DSIM_CONFIG_REG); 597 + reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK | 598 + DSIM_LANE_EN(lane)); 599 + DSI_WRITE(dsi, DSIM_CONFIG_REG, reg); 745 600 } 746 601 747 602 static int exynos_dsi_init_link(struct exynos_dsi *dsi) ··· 760 599 u32 lanes_mask; 761 600 762 601 /* Initialize FIFO pointers */ 763 - reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG); 602 + reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG); 764 603 reg &= ~0x1f; 765 - writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG); 604 + DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg); 766 605 767 606 usleep_range(9000, 11000); 768 607 769 608 reg |= 0x1f; 770 - writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG); 771 - 609 + DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg); 772 610 usleep_range(9000, 11000); 773 611 774 612 /* DSI configuration */ ··· 824 664 return -EINVAL; 825 665 } 826 666 827 - reg |= DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1); 828 - 829 - writel(reg, dsi->reg_base + DSIM_CONFIG_REG); 830 - 831 - reg |= DSIM_LANE_EN_CLK; 832 - writel(reg, dsi->reg_base + DSIM_CONFIG_REG); 833 - 834 - lanes_mask = BIT(dsi->lanes) - 1; 835 - reg |= DSIM_LANE_EN(lanes_mask); 836 - writel(reg, dsi->reg_base + DSIM_CONFIG_REG); 837 - 838 667 /* 839 668 * Use non-continuous clock mode if the periparal wants and 840 669 * host controller supports ··· 835 686 if (driver_data->has_clklane_stop && 836 687 dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { 837 688 reg |= DSIM_CLKLANE_STOP; 838 - writel(reg, dsi->reg_base + DSIM_CONFIG_REG); 839 689 } 690 + DSI_WRITE(dsi, DSIM_CONFIG_REG, reg); 691 + 692 + lanes_mask = BIT(dsi->lanes) - 1; 693 + exynos_dsi_enable_lane(dsi, lanes_mask); 840 694 841 695 /* Check clock and data lane state are stop state */ 842 696 timeout = 100; ··· 849 697 return -EFAULT; 850 698 } 851 699 852 - reg = readl(dsi->reg_base + DSIM_STATUS_REG); 700 + reg = DSI_READ(dsi, DSIM_STATUS_REG); 853 701 if ((reg & DSIM_STOP_STATE_DAT(lanes_mask)) 854 702 != DSIM_STOP_STATE_DAT(lanes_mask)) 855 703 continue; 856 704 } while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK))); 857 705 858 - reg = readl(dsi->reg_base + DSIM_ESCMODE_REG); 706 + reg = DSI_READ(dsi, DSIM_ESCMODE_REG); 859 707 reg &= ~DSIM_STOP_STATE_CNT_MASK; 860 - reg |= DSIM_STOP_STATE_CNT(0xf); 861 - writel(reg, dsi->reg_base + DSIM_ESCMODE_REG); 708 + reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]); 709 + DSI_WRITE(dsi, DSIM_ESCMODE_REG, reg); 862 710 863 711 reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff); 864 - writel(reg, dsi->reg_base + DSIM_TIMEOUT_REG); 712 + DSI_WRITE(dsi, DSIM_TIMEOUT_REG, reg); 865 713 866 714 return 0; 867 715 } ··· 869 717 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi) 870 718 { 871 719 struct videomode *vm = &dsi->vm; 720 + unsigned int num_bits_resol = dsi->driver_data->num_bits_resol; 872 721 u32 reg; 873 722 874 723 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { 875 724 reg = DSIM_CMD_ALLOW(0xf) 876 725 | DSIM_STABLE_VFP(vm->vfront_porch) 877 726 | DSIM_MAIN_VBP(vm->vback_porch); 878 - writel(reg, dsi->reg_base + DSIM_MVPORCH_REG); 727 + DSI_WRITE(dsi, DSIM_MVPORCH_REG, reg); 879 728 880 729 reg = DSIM_MAIN_HFP(vm->hfront_porch) 881 730 | DSIM_MAIN_HBP(vm->hback_porch); 882 - writel(reg, dsi->reg_base + DSIM_MHPORCH_REG); 731 + DSI_WRITE(dsi, DSIM_MHPORCH_REG, reg); 883 732 884 733 reg = DSIM_MAIN_VSA(vm->vsync_len) 885 734 | DSIM_MAIN_HSA(vm->hsync_len); 886 - writel(reg, dsi->reg_base + DSIM_MSYNC_REG); 735 + DSI_WRITE(dsi, DSIM_MSYNC_REG, reg); 887 736 } 737 + reg = DSIM_MAIN_HRESOL(vm->hactive, num_bits_resol) | 738 + DSIM_MAIN_VRESOL(vm->vactive, num_bits_resol); 888 739 889 - reg = DSIM_MAIN_HRESOL(vm->hactive) | DSIM_MAIN_VRESOL(vm->vactive); 890 - writel(reg, dsi->reg_base + DSIM_MDRESOL_REG); 740 + DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg); 891 741 892 742 dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive); 893 743 } ··· 898 744 { 899 745 u32 reg; 900 746 901 - reg = readl(dsi->reg_base + DSIM_MDRESOL_REG); 747 + reg = DSI_READ(dsi, DSIM_MDRESOL_REG); 902 748 if (enable) 903 749 reg |= DSIM_MAIN_STAND_BY; 904 750 else 905 751 reg &= ~DSIM_MAIN_STAND_BY; 906 - writel(reg, dsi->reg_base + DSIM_MDRESOL_REG); 752 + DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg); 907 753 } 908 754 909 755 static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi) ··· 911 757 int timeout = 2000; 912 758 913 759 do { 914 - u32 reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG); 760 + u32 reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG); 915 761 916 762 if (!(reg & DSIM_SFR_HEADER_FULL)) 917 763 return 0; ··· 925 771 926 772 static void exynos_dsi_set_cmd_lpm(struct exynos_dsi *dsi, bool lpm) 927 773 { 928 - u32 v = readl(dsi->reg_base + DSIM_ESCMODE_REG); 774 + u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG); 929 775 930 776 if (lpm) 931 777 v |= DSIM_CMD_LPDT_LP; 932 778 else 933 779 v &= ~DSIM_CMD_LPDT_LP; 934 780 935 - writel(v, dsi->reg_base + DSIM_ESCMODE_REG); 781 + DSI_WRITE(dsi, DSIM_ESCMODE_REG, v); 936 782 } 937 783 938 784 static void exynos_dsi_force_bta(struct exynos_dsi *dsi) 939 785 { 940 - u32 v = readl(dsi->reg_base + DSIM_ESCMODE_REG); 941 - 786 + u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG); 942 787 v |= DSIM_FORCE_BTA; 943 - writel(v, dsi->reg_base + DSIM_ESCMODE_REG); 788 + DSI_WRITE(dsi, DSIM_ESCMODE_REG, v); 944 789 } 945 790 946 791 static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi, ··· 963 810 while (length >= 4) { 964 811 reg = (payload[3] << 24) | (payload[2] << 16) 965 812 | (payload[1] << 8) | payload[0]; 966 - writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG); 813 + DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg); 967 814 payload += 4; 968 815 length -= 4; 969 816 } ··· 978 825 /* Fall through */ 979 826 case 1: 980 827 reg |= payload[0]; 981 - writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG); 828 + DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg); 982 829 break; 983 830 case 0: 984 831 /* Do nothing */ ··· 1001 848 dsi->state ^= DSIM_STATE_CMD_LPM; 1002 849 } 1003 850 1004 - writel(reg, dsi->reg_base + DSIM_PKTHDR_REG); 851 + DSI_WRITE(dsi, DSIM_PKTHDR_REG, reg); 1005 852 1006 853 if (xfer->flags & MIPI_DSI_MSG_REQ_ACK) 1007 854 exynos_dsi_force_bta(dsi); ··· 1017 864 u32 reg; 1018 865 1019 866 if (first) { 1020 - reg = readl(dsi->reg_base + DSIM_RXFIFO_REG); 867 + reg = DSI_READ(dsi, DSIM_RXFIFO_REG); 1021 868 1022 869 switch (reg & 0x3f) { 1023 870 case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE: ··· 1056 903 1057 904 /* Receive payload */ 1058 905 while (length >= 4) { 1059 - reg = readl(dsi->reg_base + DSIM_RXFIFO_REG); 906 + reg = DSI_READ(dsi, DSIM_RXFIFO_REG); 1060 907 payload[0] = (reg >> 0) & 0xff; 1061 908 payload[1] = (reg >> 8) & 0xff; 1062 909 payload[2] = (reg >> 16) & 0xff; ··· 1066 913 } 1067 914 1068 915 if (length) { 1069 - reg = readl(dsi->reg_base + DSIM_RXFIFO_REG); 916 + reg = DSI_READ(dsi, DSIM_RXFIFO_REG); 1070 917 switch (length) { 1071 918 case 3: 1072 919 payload[2] = (reg >> 16) & 0xff; ··· 1085 932 clear_fifo: 1086 933 length = DSI_RX_FIFO_SIZE / 4; 1087 934 do { 1088 - reg = readl(dsi->reg_base + DSIM_RXFIFO_REG); 935 + reg = DSI_READ(dsi, DSIM_RXFIFO_REG); 1089 936 if (reg == DSI_RX_FIFO_EMPTY) 1090 937 break; 1091 938 } while (--length); ··· 1241 1088 struct exynos_dsi *dsi = dev_id; 1242 1089 u32 status; 1243 1090 1244 - status = readl(dsi->reg_base + DSIM_INTSRC_REG); 1091 + status = DSI_READ(dsi, DSIM_INTSRC_REG); 1245 1092 if (!status) { 1246 1093 static unsigned long int j; 1247 1094 if (printk_timed_ratelimit(&j, 500)) 1248 1095 dev_warn(dsi->dev, "spurious interrupt\n"); 1249 1096 return IRQ_HANDLED; 1250 1097 } 1251 - writel(status, dsi->reg_base + DSIM_INTSRC_REG); 1098 + DSI_WRITE(dsi, DSIM_INTSRC_REG, status); 1252 1099 1253 1100 if (status & DSIM_INT_SW_RST_RELEASE) { 1254 - u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY); 1255 - writel(mask, dsi->reg_base + DSIM_INTMSK_REG); 1101 + u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY | 1102 + DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_FRAME_DONE | 1103 + DSIM_INT_RX_ECC_ERR | DSIM_INT_SW_RST_RELEASE); 1104 + DSI_WRITE(dsi, DSIM_INTMSK_REG, mask); 1256 1105 complete(&dsi->completed); 1257 1106 return IRQ_HANDLED; 1258 1107 } 1259 1108 1260 - if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY))) 1109 + if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY | 1110 + DSIM_INT_FRAME_DONE | DSIM_INT_PLL_STABLE))) 1261 1111 return IRQ_HANDLED; 1262 1112 1263 1113 if (exynos_dsi_transfer_finish(dsi)) ··· 1274 1118 struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id; 1275 1119 struct drm_encoder *encoder = dsi->display.encoder; 1276 1120 1277 - if (dsi->state & DSIM_STATE_ENABLED) 1121 + if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE) 1278 1122 exynos_drm_crtc_te_handler(encoder->crtc); 1279 1123 1280 1124 return IRQ_HANDLED; ··· 1298 1142 1299 1143 static int exynos_dsi_init(struct exynos_dsi *dsi) 1300 1144 { 1145 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1146 + 1301 1147 exynos_dsi_reset(dsi); 1302 1148 exynos_dsi_enable_irq(dsi); 1149 + 1150 + if (driver_data->reg_values[RESET_TYPE] == DSIM_FUNCRST) 1151 + exynos_dsi_enable_lane(dsi, BIT(dsi->lanes) - 1); 1152 + 1303 1153 exynos_dsi_enable_clock(dsi); 1304 - exynos_dsi_wait_for_reset(dsi); 1154 + if (driver_data->wait_for_reset) 1155 + exynos_dsi_wait_for_reset(dsi); 1305 1156 exynos_dsi_set_phy_ctrl(dsi); 1306 1157 exynos_dsi_init_link(dsi); 1307 1158 ··· 1327 1164 goto out; 1328 1165 } 1329 1166 1330 - ret = gpio_request_one(dsi->te_gpio, GPIOF_IN, "te_gpio"); 1167 + ret = gpio_request(dsi->te_gpio, "te_gpio"); 1331 1168 if (ret) { 1332 1169 dev_err(dsi->dev, "gpio request failed with %d\n", ret); 1333 1170 goto out; 1334 1171 } 1335 1172 1336 1173 te_gpio_irq = gpio_to_irq(dsi->te_gpio); 1337 - 1338 1174 irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN); 1175 + 1339 1176 ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL, 1340 1177 IRQF_TRIGGER_RISING, "TE", dsi); 1341 1178 if (ret) { ··· 1414 1251 struct exynos_dsi_transfer xfer; 1415 1252 int ret; 1416 1253 1254 + if (!(dsi->state & DSIM_STATE_ENABLED)) 1255 + return -EINVAL; 1256 + 1417 1257 if (!(dsi->state & DSIM_STATE_INITIALIZED)) { 1418 1258 ret = exynos_dsi_init(dsi); 1419 1259 if (ret) ··· 1460 1294 1461 1295 static int exynos_dsi_poweron(struct exynos_dsi *dsi) 1462 1296 { 1463 - int ret; 1297 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1298 + int ret, i; 1464 1299 1465 1300 ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1466 1301 if (ret < 0) { ··· 1469 1302 return ret; 1470 1303 } 1471 1304 1472 - ret = clk_prepare_enable(dsi->bus_clk); 1473 - if (ret < 0) { 1474 - dev_err(dsi->dev, "cannot enable bus clock %d\n", ret); 1475 - goto err_bus_clk; 1476 - } 1477 - 1478 - ret = clk_prepare_enable(dsi->pll_clk); 1479 - if (ret < 0) { 1480 - dev_err(dsi->dev, "cannot enable pll clock %d\n", ret); 1481 - goto err_pll_clk; 1305 + for (i = 0; i < driver_data->num_clks; i++) { 1306 + ret = clk_prepare_enable(dsi->clks[i]); 1307 + if (ret < 0) 1308 + goto err_clk; 1482 1309 } 1483 1310 1484 1311 ret = phy_power_on(dsi->phy); 1485 1312 if (ret < 0) { 1486 1313 dev_err(dsi->dev, "cannot enable phy %d\n", ret); 1487 - goto err_phy; 1314 + goto err_clk; 1488 1315 } 1489 1316 1490 1317 return 0; 1491 1318 1492 - err_phy: 1493 - clk_disable_unprepare(dsi->pll_clk); 1494 - err_pll_clk: 1495 - clk_disable_unprepare(dsi->bus_clk); 1496 - err_bus_clk: 1319 + err_clk: 1320 + while (--i > -1) 1321 + clk_disable_unprepare(dsi->clks[i]); 1497 1322 regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1498 1323 1499 1324 return ret; ··· 1493 1334 1494 1335 static void exynos_dsi_poweroff(struct exynos_dsi *dsi) 1495 1336 { 1496 - int ret; 1337 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1338 + int ret, i; 1497 1339 1498 1340 usleep_range(10000, 20000); 1499 1341 ··· 1510 1350 1511 1351 phy_power_off(dsi->phy); 1512 1352 1513 - clk_disable_unprepare(dsi->pll_clk); 1514 - clk_disable_unprepare(dsi->bus_clk); 1353 + for (i = driver_data->num_clks - 1; i > -1; i--) 1354 + clk_disable_unprepare(dsi->clks[i]); 1515 1355 1516 1356 ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1517 1357 if (ret < 0) ··· 1529 1369 if (ret < 0) 1530 1370 return ret; 1531 1371 1372 + dsi->state |= DSIM_STATE_ENABLED; 1373 + 1532 1374 ret = drm_panel_prepare(dsi->panel); 1533 1375 if (ret < 0) { 1376 + dsi->state &= ~DSIM_STATE_ENABLED; 1534 1377 exynos_dsi_poweroff(dsi); 1535 1378 return ret; 1536 1379 } 1537 1380 1538 1381 exynos_dsi_set_display_mode(dsi); 1539 1382 exynos_dsi_set_display_enable(dsi, true); 1540 - 1541 - dsi->state |= DSIM_STATE_ENABLED; 1542 1383 1543 1384 ret = drm_panel_enable(dsi->panel); 1544 1385 if (ret < 0) { ··· 1550 1389 return ret; 1551 1390 } 1552 1391 1392 + dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; 1393 + 1553 1394 return 0; 1554 1395 } 1555 1396 ··· 1560 1397 if (!(dsi->state & DSIM_STATE_ENABLED)) 1561 1398 return; 1562 1399 1400 + dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; 1401 + 1563 1402 drm_panel_disable(dsi->panel); 1564 1403 exynos_dsi_set_display_enable(dsi, false); 1565 1404 drm_panel_unprepare(dsi->panel); 1566 - exynos_dsi_poweroff(dsi); 1567 1405 1568 1406 dsi->state &= ~DSIM_STATE_ENABLED; 1407 + 1408 + exynos_dsi_poweroff(dsi); 1569 1409 } 1570 1410 1571 1411 static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode) ··· 1623 1457 } 1624 1458 1625 1459 static struct drm_connector_funcs exynos_dsi_connector_funcs = { 1626 - .dpms = drm_helper_connector_dpms, 1460 + .dpms = drm_atomic_helper_connector_dpms, 1627 1461 .detect = exynos_dsi_detect, 1628 1462 .fill_modes = drm_helper_probe_single_connector_modes, 1629 1463 .destroy = exynos_dsi_connector_destroy, 1464 + .reset = drm_atomic_helper_connector_reset, 1465 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1466 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1630 1467 }; 1631 1468 1632 1469 static int exynos_dsi_get_modes(struct drm_connector *connector) ··· 1796 1627 1797 1628 ret = exynos_dsi_of_read_u32(ep, "samsung,esc-clock-frequency", 1798 1629 &dsi->esc_clk_rate); 1630 + if (ret < 0) 1631 + goto end; 1799 1632 1633 + of_node_put(ep); 1634 + 1635 + ep = of_graph_get_next_endpoint(node, NULL); 1636 + if (!ep) { 1637 + ret = -ENXIO; 1638 + goto end; 1639 + } 1640 + 1641 + dsi->bridge_node = of_graph_get_remote_port_parent(ep); 1642 + if (!dsi->bridge_node) { 1643 + ret = -ENXIO; 1644 + goto end; 1645 + } 1800 1646 end: 1801 1647 of_node_put(ep); 1802 1648 ··· 1824 1640 struct exynos_drm_display *display = dev_get_drvdata(dev); 1825 1641 struct exynos_dsi *dsi = display_to_dsi(display); 1826 1642 struct drm_device *drm_dev = data; 1643 + struct drm_bridge *bridge; 1827 1644 int ret; 1828 1645 1829 1646 ret = exynos_drm_create_enc_conn(drm_dev, display); ··· 1832 1647 DRM_ERROR("Encoder create [%d] failed with %d\n", 1833 1648 display->type, ret); 1834 1649 return ret; 1650 + } 1651 + 1652 + bridge = of_drm_find_bridge(dsi->bridge_node); 1653 + if (bridge) { 1654 + display->encoder->bridge = bridge; 1655 + drm_bridge_attach(drm_dev, bridge); 1835 1656 } 1836 1657 1837 1658 return mipi_dsi_host_register(&dsi->dsi_host); ··· 1864 1673 struct device *dev = &pdev->dev; 1865 1674 struct resource *res; 1866 1675 struct exynos_dsi *dsi; 1867 - int ret; 1676 + int ret, i; 1868 1677 1869 1678 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); 1870 1679 if (!dsi) ··· 1872 1681 1873 1682 dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD; 1874 1683 dsi->display.ops = &exynos_dsi_display_ops; 1875 - 1876 - ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CONNECTOR, 1877 - dsi->display.type); 1878 - if (ret) 1879 - return ret; 1880 1684 1881 1685 /* To be checked as invalid one */ 1882 1686 dsi->te_gpio = -ENOENT; ··· 1888 1702 1889 1703 ret = exynos_dsi_parse_dt(dsi); 1890 1704 if (ret) 1891 - goto err_del_component; 1705 + return ret; 1892 1706 1893 1707 dsi->supplies[0].supply = "vddcore"; 1894 1708 dsi->supplies[1].supply = "vddio"; ··· 1899 1713 return -EPROBE_DEFER; 1900 1714 } 1901 1715 1902 - dsi->pll_clk = devm_clk_get(dev, "pll_clk"); 1903 - if (IS_ERR(dsi->pll_clk)) { 1904 - dev_info(dev, "failed to get dsi pll input clock\n"); 1905 - ret = PTR_ERR(dsi->pll_clk); 1906 - goto err_del_component; 1907 - } 1716 + dsi->clks = devm_kzalloc(dev, 1717 + sizeof(*dsi->clks) * dsi->driver_data->num_clks, 1718 + GFP_KERNEL); 1719 + if (!dsi->clks) 1720 + return -ENOMEM; 1908 1721 1909 - dsi->bus_clk = devm_clk_get(dev, "bus_clk"); 1910 - if (IS_ERR(dsi->bus_clk)) { 1911 - dev_info(dev, "failed to get dsi bus clock\n"); 1912 - ret = PTR_ERR(dsi->bus_clk); 1913 - goto err_del_component; 1722 + for (i = 0; i < dsi->driver_data->num_clks; i++) { 1723 + dsi->clks[i] = devm_clk_get(dev, clk_names[i]); 1724 + if (IS_ERR(dsi->clks[i])) { 1725 + if (strcmp(clk_names[i], "sclk_mipi") == 0) { 1726 + strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME); 1727 + i--; 1728 + continue; 1729 + } 1730 + 1731 + dev_info(dev, "failed to get the clock: %s\n", 1732 + clk_names[i]); 1733 + return PTR_ERR(dsi->clks[i]); 1734 + } 1914 1735 } 1915 1736 1916 1737 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1917 1738 dsi->reg_base = devm_ioremap_resource(dev, res); 1918 1739 if (IS_ERR(dsi->reg_base)) { 1919 1740 dev_err(dev, "failed to remap io region\n"); 1920 - ret = PTR_ERR(dsi->reg_base); 1921 - goto err_del_component; 1741 + return PTR_ERR(dsi->reg_base); 1922 1742 } 1923 1743 1924 1744 dsi->phy = devm_phy_get(dev, "dsim"); 1925 1745 if (IS_ERR(dsi->phy)) { 1926 1746 dev_info(dev, "failed to get dsim phy\n"); 1927 - ret = PTR_ERR(dsi->phy); 1928 - goto err_del_component; 1747 + return PTR_ERR(dsi->phy); 1929 1748 } 1930 1749 1931 1750 dsi->irq = platform_get_irq(pdev, 0); 1932 1751 if (dsi->irq < 0) { 1933 1752 dev_err(dev, "failed to request dsi irq resource\n"); 1934 - ret = dsi->irq; 1935 - goto err_del_component; 1753 + return dsi->irq; 1936 1754 } 1937 1755 1938 1756 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); ··· 1945 1755 dev_name(dev), dsi); 1946 1756 if (ret) { 1947 1757 dev_err(dev, "failed to request dsi irq\n"); 1948 - goto err_del_component; 1758 + return ret; 1949 1759 } 1950 1760 1951 1761 platform_set_drvdata(pdev, &dsi->display); 1952 1762 1953 - ret = component_add(dev, &exynos_dsi_component_ops); 1954 - if (ret) 1955 - goto err_del_component; 1956 - 1957 - return ret; 1958 - 1959 - err_del_component: 1960 - exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 1961 - return ret; 1763 + return component_add(dev, &exynos_dsi_component_ops); 1962 1764 } 1963 1765 1964 1766 static int exynos_dsi_remove(struct platform_device *pdev) 1965 1767 { 1966 1768 component_del(&pdev->dev, &exynos_dsi_component_ops); 1967 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 1968 1769 1969 1770 return 0; 1970 1771 }
+6 -29
drivers/gpu/drm/exynos/exynos_drm_encoder.c
··· 32 32 struct exynos_drm_display *display; 33 33 }; 34 34 35 - static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) 36 - { 37 - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); 38 - struct exynos_drm_display *display = exynos_encoder->display; 39 - 40 - DRM_DEBUG_KMS("encoder dpms: %d\n", mode); 41 - 42 - if (display->ops->dpms) 43 - display->ops->dpms(display, mode); 44 - } 45 - 46 35 static bool 47 36 exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, 48 37 const struct drm_display_mode *mode, ··· 65 76 display->ops->mode_set(display, adjusted_mode); 66 77 } 67 78 68 - static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) 69 - { 70 - /* drm framework doesn't check NULL. */ 71 - } 72 - 73 - static void exynos_drm_encoder_commit(struct drm_encoder *encoder) 79 + static void exynos_drm_encoder_enable(struct drm_encoder *encoder) 74 80 { 75 81 struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); 76 82 struct exynos_drm_display *display = exynos_encoder->display; ··· 79 95 80 96 static void exynos_drm_encoder_disable(struct drm_encoder *encoder) 81 97 { 82 - struct drm_plane *plane; 83 - struct drm_device *dev = encoder->dev; 98 + struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); 99 + struct exynos_drm_display *display = exynos_encoder->display; 84 100 85 - exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 86 - 87 - /* all planes connected to this encoder should be also disabled. */ 88 - drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 89 - if (plane->crtc && (plane->crtc == encoder->crtc)) 90 - plane->funcs->disable_plane(plane); 91 - } 101 + if (display->ops->dpms) 102 + display->ops->dpms(display, DRM_MODE_DPMS_OFF); 92 103 } 93 104 94 105 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { 95 - .dpms = exynos_drm_encoder_dpms, 96 106 .mode_fixup = exynos_drm_encoder_mode_fixup, 97 107 .mode_set = exynos_drm_encoder_mode_set, 98 - .prepare = exynos_drm_encoder_prepare, 99 - .commit = exynos_drm_encoder_commit, 108 + .enable = exynos_drm_encoder_enable, 100 109 .disable = exynos_drm_encoder_disable, 101 110 }; 102 111
+39
drivers/gpu/drm/exynos/exynos_drm_fb.c
··· 16 16 #include <drm/drm_crtc.h> 17 17 #include <drm/drm_crtc_helper.h> 18 18 #include <drm/drm_fb_helper.h> 19 + #include <drm/drm_atomic.h> 20 + #include <drm/drm_atomic_helper.h> 19 21 #include <uapi/drm/exynos_drm.h> 20 22 21 23 #include "exynos_drm_drv.h" ··· 267 265 exynos_drm_fbdev_init(dev); 268 266 } 269 267 268 + static int exynos_atomic_commit(struct drm_device *dev, 269 + struct drm_atomic_state *state, 270 + bool async) 271 + { 272 + int ret; 273 + 274 + ret = drm_atomic_helper_prepare_planes(dev, state); 275 + if (ret) 276 + return ret; 277 + 278 + /* This is the point of no return */ 279 + 280 + drm_atomic_helper_swap_state(dev, state); 281 + 282 + drm_atomic_helper_commit_modeset_disables(dev, state); 283 + 284 + drm_atomic_helper_commit_modeset_enables(dev, state); 285 + 286 + /* 287 + * Exynos can't update planes with CRTCs and encoders disabled, 288 + * its updates routines, specially for FIMD, requires the clocks 289 + * to be enabled. So it is necessary to handle the modeset operations 290 + * *before* the commit_planes() step, this way it will always 291 + * have the relevant clocks enabled to perform the update. 292 + */ 293 + 294 + drm_atomic_helper_commit_planes(dev, state); 295 + 296 + drm_atomic_helper_cleanup_planes(dev, state); 297 + 298 + drm_atomic_state_free(state); 299 + 300 + return 0; 301 + } 302 + 270 303 static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { 271 304 .fb_create = exynos_user_fb_create, 272 305 .output_poll_changed = exynos_drm_output_poll_changed, 306 + .atomic_check = drm_atomic_helper_check, 307 + .atomic_commit = exynos_atomic_commit, 273 308 }; 274 309 275 310 void exynos_drm_mode_config_init(struct drm_device *dev)
-3
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
··· 275 275 276 276 } 277 277 278 - /* disable all the possible outputs/crtcs before entering KMS mode */ 279 - drm_helper_disable_unused_functions(dev); 280 - 281 278 ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); 282 279 if (ret < 0) { 283 280 DRM_ERROR("failed to set up hw configuration.\n");
+117 -206
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 196 196 return (struct fimd_driver_data *)of_id->data; 197 197 } 198 198 199 + static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) 200 + { 201 + struct fimd_context *ctx = crtc->ctx; 202 + u32 val; 203 + 204 + if (ctx->suspended) 205 + return -EPERM; 206 + 207 + if (!test_and_set_bit(0, &ctx->irq_flags)) { 208 + val = readl(ctx->regs + VIDINTCON0); 209 + 210 + val |= VIDINTCON0_INT_ENABLE; 211 + 212 + if (ctx->i80_if) { 213 + val |= VIDINTCON0_INT_I80IFDONE; 214 + val |= VIDINTCON0_INT_SYSMAINCON; 215 + val &= ~VIDINTCON0_INT_SYSSUBCON; 216 + } else { 217 + val |= VIDINTCON0_INT_FRAME; 218 + 219 + val &= ~VIDINTCON0_FRAMESEL0_MASK; 220 + val |= VIDINTCON0_FRAMESEL0_VSYNC; 221 + val &= ~VIDINTCON0_FRAMESEL1_MASK; 222 + val |= VIDINTCON0_FRAMESEL1_NONE; 223 + } 224 + 225 + writel(val, ctx->regs + VIDINTCON0); 226 + } 227 + 228 + return 0; 229 + } 230 + 231 + static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) 232 + { 233 + struct fimd_context *ctx = crtc->ctx; 234 + u32 val; 235 + 236 + if (ctx->suspended) 237 + return; 238 + 239 + if (test_and_clear_bit(0, &ctx->irq_flags)) { 240 + val = readl(ctx->regs + VIDINTCON0); 241 + 242 + val &= ~VIDINTCON0_INT_ENABLE; 243 + 244 + if (ctx->i80_if) { 245 + val &= ~VIDINTCON0_INT_I80IFDONE; 246 + val &= ~VIDINTCON0_INT_SYSMAINCON; 247 + val &= ~VIDINTCON0_INT_SYSSUBCON; 248 + } else 249 + val &= ~VIDINTCON0_INT_FRAME; 250 + 251 + writel(val, ctx->regs + VIDINTCON0); 252 + } 253 + } 254 + 199 255 static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc) 200 256 { 201 257 struct fimd_context *ctx = crtc->ctx; ··· 298 242 writel(val, ctx->regs + SHADOWCON); 299 243 } 300 244 301 - static void fimd_clear_channel(struct fimd_context *ctx) 245 + static void fimd_clear_channels(struct exynos_drm_crtc *crtc) 302 246 { 247 + struct fimd_context *ctx = crtc->ctx; 303 248 unsigned int win, ch_enabled = 0; 304 249 305 250 DRM_DEBUG_KMS("%s\n", __FILE__); 251 + 252 + /* Hardware is in unknown state, so ensure it gets enabled properly */ 253 + pm_runtime_get_sync(ctx->dev); 254 + 255 + clk_prepare_enable(ctx->bus_clk); 256 + clk_prepare_enable(ctx->lcd_clk); 306 257 307 258 /* Check if any channel is enabled. */ 308 259 for (win = 0; win < WINDOWS_NR; win++) { ··· 328 265 329 266 /* Wait for vsync, as disable channel takes effect at next vsync */ 330 267 if (ch_enabled) { 331 - unsigned int state = ctx->suspended; 268 + int pipe = ctx->pipe; 332 269 333 - ctx->suspended = 0; 270 + /* ensure that vblank interrupt won't be reported to core */ 271 + ctx->suspended = false; 272 + ctx->pipe = -1; 273 + 274 + fimd_enable_vblank(ctx->crtc); 334 275 fimd_wait_for_vblank(ctx->crtc); 335 - ctx->suspended = state; 336 - } 337 - } 276 + fimd_disable_vblank(ctx->crtc); 338 277 339 - static int fimd_iommu_attach_devices(struct fimd_context *ctx, 340 - struct drm_device *drm_dev) 341 - { 342 - 343 - /* attach this sub driver to iommu mapping if supported. */ 344 - if (is_drm_iommu_supported(ctx->drm_dev)) { 345 - int ret; 346 - 347 - /* 348 - * If any channel is already active, iommu will throw 349 - * a PAGE FAULT when enabled. So clear any channel if enabled. 350 - */ 351 - fimd_clear_channel(ctx); 352 - ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev); 353 - if (ret) { 354 - DRM_ERROR("drm_iommu_attach failed.\n"); 355 - return ret; 356 - } 357 - 278 + ctx->suspended = true; 279 + ctx->pipe = pipe; 358 280 } 359 281 360 - return 0; 282 + clk_disable_unprepare(ctx->lcd_clk); 283 + clk_disable_unprepare(ctx->bus_clk); 284 + 285 + pm_runtime_put(ctx->dev); 361 286 } 362 287 363 288 static void fimd_iommu_detach_devices(struct fimd_context *ctx) ··· 388 337 static void fimd_commit(struct exynos_drm_crtc *crtc) 389 338 { 390 339 struct fimd_context *ctx = crtc->ctx; 391 - struct drm_display_mode *mode = &crtc->base.mode; 340 + struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; 392 341 struct fimd_driver_data *driver_data = ctx->driver_data; 393 342 void *timing_base = ctx->regs + driver_data->timing_base; 394 343 u32 val, clkdiv; ··· 485 434 writel(val, ctx->regs + VIDCON0); 486 435 } 487 436 488 - static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) 489 - { 490 - struct fimd_context *ctx = crtc->ctx; 491 - u32 val; 492 - 493 - if (ctx->suspended) 494 - return -EPERM; 495 - 496 - if (!test_and_set_bit(0, &ctx->irq_flags)) { 497 - val = readl(ctx->regs + VIDINTCON0); 498 - 499 - val |= VIDINTCON0_INT_ENABLE; 500 - 501 - if (ctx->i80_if) { 502 - val |= VIDINTCON0_INT_I80IFDONE; 503 - val |= VIDINTCON0_INT_SYSMAINCON; 504 - val &= ~VIDINTCON0_INT_SYSSUBCON; 505 - } else { 506 - val |= VIDINTCON0_INT_FRAME; 507 - 508 - val &= ~VIDINTCON0_FRAMESEL0_MASK; 509 - val |= VIDINTCON0_FRAMESEL0_VSYNC; 510 - val &= ~VIDINTCON0_FRAMESEL1_MASK; 511 - val |= VIDINTCON0_FRAMESEL1_NONE; 512 - } 513 - 514 - writel(val, ctx->regs + VIDINTCON0); 515 - } 516 - 517 - return 0; 518 - } 519 - 520 - static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) 521 - { 522 - struct fimd_context *ctx = crtc->ctx; 523 - u32 val; 524 - 525 - if (ctx->suspended) 526 - return; 527 - 528 - if (test_and_clear_bit(0, &ctx->irq_flags)) { 529 - val = readl(ctx->regs + VIDINTCON0); 530 - 531 - val &= ~VIDINTCON0_INT_ENABLE; 532 - 533 - if (ctx->i80_if) { 534 - val &= ~VIDINTCON0_INT_I80IFDONE; 535 - val &= ~VIDINTCON0_INT_SYSMAINCON; 536 - val &= ~VIDINTCON0_INT_SYSSUBCON; 537 - } else 538 - val &= ~VIDINTCON0_INT_FRAME; 539 - 540 - writel(val, ctx->regs + VIDINTCON0); 541 - } 542 - } 543 437 544 438 static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) 545 439 { ··· 630 634 631 635 plane = &ctx->planes[win]; 632 636 633 - /* If suspended, enable this on resume */ 634 - if (ctx->suspended) { 635 - plane->resume = true; 637 + if (ctx->suspended) 636 638 return; 637 - } 638 639 639 640 /* 640 641 * SHADOWCON/PRTCON register is used for enabling timing. ··· 721 728 /* Enable DMA channel and unprotect windows */ 722 729 fimd_shadow_protect_win(ctx, win, false); 723 730 724 - plane->enabled = true; 725 - 726 731 if (ctx->i80_if) 727 732 atomic_set(&ctx->win_updated, 1); 728 733 } ··· 735 744 736 745 plane = &ctx->planes[win]; 737 746 738 - if (ctx->suspended) { 739 - /* do not resume this window*/ 740 - plane->resume = false; 747 + if (ctx->suspended) 741 748 return; 742 - } 743 749 744 750 /* protect windows */ 745 751 fimd_shadow_protect_win(ctx, win, true); ··· 748 760 749 761 /* unprotect windows */ 750 762 fimd_shadow_protect_win(ctx, win, false); 751 - 752 - plane->enabled = false; 753 763 } 754 764 755 - static void fimd_window_suspend(struct fimd_context *ctx) 765 + static void fimd_enable(struct exynos_drm_crtc *crtc) 756 766 { 757 - struct exynos_drm_plane *plane; 758 - int i; 759 - 760 - for (i = 0; i < WINDOWS_NR; i++) { 761 - plane = &ctx->planes[i]; 762 - plane->resume = plane->enabled; 763 - if (plane->enabled) 764 - fimd_win_disable(ctx->crtc, i); 765 - } 766 - } 767 - 768 - static void fimd_window_resume(struct fimd_context *ctx) 769 - { 770 - struct exynos_drm_plane *plane; 771 - int i; 772 - 773 - for (i = 0; i < WINDOWS_NR; i++) { 774 - plane = &ctx->planes[i]; 775 - plane->enabled = plane->resume; 776 - plane->resume = false; 777 - } 778 - } 779 - 780 - static void fimd_apply(struct fimd_context *ctx) 781 - { 782 - struct exynos_drm_plane *plane; 783 - int i; 784 - 785 - for (i = 0; i < WINDOWS_NR; i++) { 786 - plane = &ctx->planes[i]; 787 - if (plane->enabled) 788 - fimd_win_commit(ctx->crtc, i); 789 - else 790 - fimd_win_disable(ctx->crtc, i); 791 - } 792 - 793 - fimd_commit(ctx->crtc); 794 - } 795 - 796 - static int fimd_poweron(struct fimd_context *ctx) 797 - { 767 + struct fimd_context *ctx = crtc->ctx; 798 768 int ret; 799 769 800 770 if (!ctx->suspended) 801 - return 0; 771 + return; 802 772 803 773 ctx->suspended = false; 804 774 ··· 765 819 ret = clk_prepare_enable(ctx->bus_clk); 766 820 if (ret < 0) { 767 821 DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret); 768 - goto bus_clk_err; 822 + return; 769 823 } 770 824 771 825 ret = clk_prepare_enable(ctx->lcd_clk); 772 826 if (ret < 0) { 773 827 DRM_ERROR("Failed to prepare_enable the lcd clk [%d]\n", ret); 774 - goto lcd_clk_err; 828 + return; 775 829 } 776 830 777 831 /* if vblank was enabled status, enable it again. */ 778 - if (test_and_clear_bit(0, &ctx->irq_flags)) { 779 - ret = fimd_enable_vblank(ctx->crtc); 780 - if (ret) { 781 - DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); 782 - goto enable_vblank_err; 783 - } 784 - } 832 + if (test_and_clear_bit(0, &ctx->irq_flags)) 833 + fimd_enable_vblank(ctx->crtc); 785 834 786 - fimd_window_resume(ctx); 787 - 788 - fimd_apply(ctx); 789 - 790 - return 0; 791 - 792 - enable_vblank_err: 793 - clk_disable_unprepare(ctx->lcd_clk); 794 - lcd_clk_err: 795 - clk_disable_unprepare(ctx->bus_clk); 796 - bus_clk_err: 797 - ctx->suspended = true; 798 - return ret; 835 + fimd_commit(ctx->crtc); 799 836 } 800 837 801 - static int fimd_poweroff(struct fimd_context *ctx) 838 + static void fimd_disable(struct exynos_drm_crtc *crtc) 802 839 { 840 + struct fimd_context *ctx = crtc->ctx; 841 + int i; 842 + 803 843 if (ctx->suspended) 804 - return 0; 844 + return; 805 845 806 846 /* 807 847 * We need to make sure that all windows are disabled before we 808 848 * suspend that connector. Otherwise we might try to scan from 809 849 * a destroyed buffer later. 810 850 */ 811 - fimd_window_suspend(ctx); 851 + for (i = 0; i < WINDOWS_NR; i++) 852 + fimd_win_disable(crtc, i); 853 + 854 + fimd_enable_vblank(crtc); 855 + fimd_wait_for_vblank(crtc); 856 + fimd_disable_vblank(crtc); 857 + 858 + writel(0, ctx->regs + VIDCON0); 812 859 813 860 clk_disable_unprepare(ctx->lcd_clk); 814 861 clk_disable_unprepare(ctx->bus_clk); ··· 809 870 pm_runtime_put_sync(ctx->dev); 810 871 811 872 ctx->suspended = true; 812 - return 0; 813 - } 814 - 815 - static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode) 816 - { 817 - DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); 818 - 819 - switch (mode) { 820 - case DRM_MODE_DPMS_ON: 821 - fimd_poweron(crtc->ctx); 822 - break; 823 - case DRM_MODE_DPMS_STANDBY: 824 - case DRM_MODE_DPMS_SUSPEND: 825 - case DRM_MODE_DPMS_OFF: 826 - fimd_poweroff(crtc->ctx); 827 - break; 828 - default: 829 - DRM_DEBUG_KMS("unspecified mode %d\n", mode); 830 - break; 831 - } 832 873 } 833 874 834 875 static void fimd_trigger(struct device *dev) ··· 883 964 } 884 965 885 966 static const struct exynos_drm_crtc_ops fimd_crtc_ops = { 886 - .dpms = fimd_dpms, 967 + .enable = fimd_enable, 968 + .disable = fimd_disable, 887 969 .mode_fixup = fimd_mode_fixup, 888 970 .commit = fimd_commit, 889 971 .enable_vblank = fimd_enable_vblank, ··· 894 974 .win_disable = fimd_win_disable, 895 975 .te_handler = fimd_te_handler, 896 976 .clock_enable = fimd_dp_clock_enable, 977 + .clear_channels = fimd_clear_channels, 897 978 }; 898 979 899 980 static irqreturn_t fimd_irq_handler(int irq, void *dev_id) ··· 964 1043 if (ctx->display) 965 1044 exynos_drm_create_enc_conn(drm_dev, ctx->display); 966 1045 967 - return fimd_iommu_attach_devices(ctx, drm_dev); 1046 + ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, dev); 1047 + if (ret) 1048 + priv->pipe--; 1049 + 1050 + return ret; 968 1051 } 969 1052 970 1053 static void fimd_unbind(struct device *dev, struct device *master, ··· 976 1051 { 977 1052 struct fimd_context *ctx = dev_get_drvdata(dev); 978 1053 979 - fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF); 1054 + fimd_disable(ctx->crtc); 980 1055 981 1056 fimd_iommu_detach_devices(ctx); 982 1057 ··· 1003 1078 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 1004 1079 if (!ctx) 1005 1080 return -ENOMEM; 1006 - 1007 - ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, 1008 - EXYNOS_DISPLAY_TYPE_LCD); 1009 - if (ret) 1010 - return ret; 1011 1081 1012 1082 ctx->dev = dev; 1013 1083 ctx->suspended = true; ··· 1054 1134 ctx->bus_clk = devm_clk_get(dev, "fimd"); 1055 1135 if (IS_ERR(ctx->bus_clk)) { 1056 1136 dev_err(dev, "failed to get bus clock\n"); 1057 - ret = PTR_ERR(ctx->bus_clk); 1058 - goto err_del_component; 1137 + return PTR_ERR(ctx->bus_clk); 1059 1138 } 1060 1139 1061 1140 ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd"); 1062 1141 if (IS_ERR(ctx->lcd_clk)) { 1063 1142 dev_err(dev, "failed to get lcd clock\n"); 1064 - ret = PTR_ERR(ctx->lcd_clk); 1065 - goto err_del_component; 1143 + return PTR_ERR(ctx->lcd_clk); 1066 1144 } 1067 1145 1068 1146 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1069 1147 1070 1148 ctx->regs = devm_ioremap_resource(dev, res); 1071 - if (IS_ERR(ctx->regs)) { 1072 - ret = PTR_ERR(ctx->regs); 1073 - goto err_del_component; 1074 - } 1149 + if (IS_ERR(ctx->regs)) 1150 + return PTR_ERR(ctx->regs); 1075 1151 1076 1152 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 1077 1153 ctx->i80_if ? "lcd_sys" : "vsync"); 1078 1154 if (!res) { 1079 1155 dev_err(dev, "irq request failed.\n"); 1080 - ret = -ENXIO; 1081 - goto err_del_component; 1156 + return -ENXIO; 1082 1157 } 1083 1158 1084 1159 ret = devm_request_irq(dev, res->start, fimd_irq_handler, 1085 1160 0, "drm_fimd", ctx); 1086 1161 if (ret) { 1087 1162 dev_err(dev, "irq request failed.\n"); 1088 - goto err_del_component; 1163 + return ret; 1089 1164 } 1090 1165 1091 1166 init_waitqueue_head(&ctx->wait_vsync_queue); ··· 1090 1175 1091 1176 ctx->display = exynos_dpi_probe(dev); 1092 1177 if (IS_ERR(ctx->display)) { 1093 - ret = PTR_ERR(ctx->display); 1094 - goto err_del_component; 1178 + return PTR_ERR(ctx->display); 1095 1179 } 1096 1180 1097 1181 pm_runtime_enable(dev); ··· 1104 1190 err_disable_pm_runtime: 1105 1191 pm_runtime_disable(dev); 1106 1192 1107 - err_del_component: 1108 - exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC); 1109 1193 return ret; 1110 1194 } 1111 1195 ··· 1112 1200 pm_runtime_disable(&pdev->dev); 1113 1201 1114 1202 component_del(&pdev->dev, &fimd_component_ops); 1115 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1116 1203 1117 1204 return 0; 1118 1205 }
-2
drivers/gpu/drm/exynos/exynos_drm_gem.h
··· 61 61 * or at framebuffer creation. 62 62 * @size: size requested from user, in bytes and this size is aligned 63 63 * in page unit. 64 - * @vma: a pointer to vm_area. 65 64 * @flags: indicate memory type to allocated buffer and cache attruibute. 66 65 * 67 66 * P.S. this object would be transferred to user as kms_bo.handle so ··· 70 71 struct drm_gem_object base; 71 72 struct exynos_drm_gem_buf *buffer; 72 73 unsigned long size; 73 - struct vm_area_struct *vma; 74 74 unsigned int flags; 75 75 }; 76 76
+19 -2
drivers/gpu/drm/exynos/exynos_drm_iommu.c
··· 100 100 101 101 dma_set_max_seg_size(subdrv_dev, 0xffffffffu); 102 102 103 + if (subdrv_dev->archdata.mapping) 104 + arm_iommu_detach_device(subdrv_dev); 105 + 103 106 ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping); 104 107 if (ret < 0) { 105 108 DRM_DEBUG_KMS("failed iommu attach.\n"); ··· 117 114 * If iommu attach succeeded, the sub driver would have dma_ops 118 115 * for iommu and also all sub drivers have same dma_ops. 119 116 */ 120 - if (!dev->archdata.dma_ops) 121 - dev->archdata.dma_ops = subdrv_dev->archdata.dma_ops; 117 + if (get_dma_ops(dev) == get_dma_ops(NULL)) 118 + set_dma_ops(dev, get_dma_ops(subdrv_dev)); 122 119 123 120 return 0; 124 121 } ··· 143 140 144 141 iommu_detach_device(mapping->domain, subdrv_dev); 145 142 drm_release_iommu_mapping(drm_dev); 143 + } 144 + 145 + int drm_iommu_attach_device_if_possible(struct exynos_drm_crtc *exynos_crtc, 146 + struct drm_device *drm_dev, struct device *subdrv_dev) 147 + { 148 + int ret = 0; 149 + 150 + if (is_drm_iommu_supported(drm_dev)) { 151 + if (exynos_crtc->ops->clear_channels) 152 + exynos_crtc->ops->clear_channels(exynos_crtc); 153 + return drm_iommu_attach_device(drm_dev, subdrv_dev); 154 + } 155 + 156 + return ret; 146 157 }
+11
drivers/gpu/drm/exynos/exynos_drm_iommu.h
··· 38 38 #endif 39 39 } 40 40 41 + int drm_iommu_attach_device_if_possible( 42 + struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev, 43 + struct device *subdrv_dev); 44 + 41 45 #else 42 46 43 47 static inline int drm_create_iommu_mapping(struct drm_device *drm_dev) ··· 67 63 static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) 68 64 { 69 65 return false; 66 + } 67 + 68 + static inline int drm_iommu_attach_device_if_possible( 69 + struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev, 70 + struct device *subdrv_dev) 71 + { 72 + return 0; 70 73 } 71 74 72 75 #endif
+39 -42
drivers/gpu/drm/exynos/exynos_drm_ipp.c
··· 45 45 #define get_ipp_context(dev) platform_get_drvdata(to_platform_device(dev)) 46 46 #define ipp_is_m2m_cmd(c) (c == IPP_CMD_M2M) 47 47 48 - /* platform device pointer for ipp device. */ 49 - static struct platform_device *exynos_drm_ipp_pdev; 50 - 51 48 /* 52 49 * A structure of event. 53 50 * ··· 98 101 static LIST_HEAD(exynos_drm_ippdrv_list); 99 102 static DEFINE_MUTEX(exynos_drm_ippdrv_lock); 100 103 static BLOCKING_NOTIFIER_HEAD(exynos_drm_ippnb_list); 101 - 102 - int exynos_platform_device_ipp_register(void) 103 - { 104 - struct platform_device *pdev; 105 - 106 - if (exynos_drm_ipp_pdev) 107 - return -EEXIST; 108 - 109 - pdev = platform_device_register_simple("exynos-drm-ipp", -1, NULL, 0); 110 - if (IS_ERR(pdev)) 111 - return PTR_ERR(pdev); 112 - 113 - exynos_drm_ipp_pdev = pdev; 114 - 115 - return 0; 116 - } 117 - 118 - void exynos_platform_device_ipp_unregister(void) 119 - { 120 - if (exynos_drm_ipp_pdev) { 121 - platform_device_unregister(exynos_drm_ipp_pdev); 122 - exynos_drm_ipp_pdev = NULL; 123 - } 124 - } 125 104 126 105 int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv) 127 106 { ··· 455 482 { 456 483 struct drm_exynos_ipp_config *ipp_cfg; 457 484 unsigned int num_plane; 458 - unsigned long min_size, size; 459 - unsigned int bpp; 485 + unsigned long size, buf_size = 0, plane_size, img_size = 0; 486 + unsigned int bpp, width, height; 460 487 int i; 461 488 462 - /* The property id should already be varified */ 463 - ipp_cfg = &c_node->property.config[m_node->prop_id]; 489 + ipp_cfg = &c_node->property.config[m_node->ops_id]; 464 490 num_plane = drm_format_num_planes(ipp_cfg->fmt); 465 491 466 492 /** ··· 470 498 * but it seems more than enough 471 499 */ 472 500 for (i = 0; i < num_plane; ++i) { 473 - if (!m_node->buf_info.handles[i]) { 474 - DRM_ERROR("invalid handle for plane %d\n", i); 475 - return -EINVAL; 476 - } 501 + width = ipp_cfg->sz.hsize; 502 + height = ipp_cfg->sz.vsize; 477 503 bpp = drm_format_plane_cpp(ipp_cfg->fmt, i); 478 - min_size = (ipp_cfg->sz.hsize * ipp_cfg->sz.vsize * bpp) >> 3; 479 - size = exynos_drm_gem_get_size(drm_dev, 480 - m_node->buf_info.handles[i], 481 - c_node->filp); 482 - if (min_size > size) { 483 - DRM_ERROR("invalid size for plane %d\n", i); 484 - return -EINVAL; 504 + 505 + /* 506 + * The result of drm_format_plane_cpp() for chroma planes must 507 + * be used with drm_format_xxxx_chroma_subsampling() for 508 + * correct result. 509 + */ 510 + if (i > 0) { 511 + width /= drm_format_horz_chroma_subsampling( 512 + ipp_cfg->fmt); 513 + height /= drm_format_vert_chroma_subsampling( 514 + ipp_cfg->fmt); 515 + } 516 + plane_size = width * height * bpp; 517 + img_size += plane_size; 518 + 519 + if (m_node->buf_info.handles[i]) { 520 + size = exynos_drm_gem_get_size(drm_dev, 521 + m_node->buf_info.handles[i], 522 + c_node->filp); 523 + if (plane_size > size) { 524 + DRM_ERROR( 525 + "buffer %d is smaller than required\n", 526 + i); 527 + return -EINVAL; 528 + } 529 + 530 + buf_size += size; 485 531 } 486 532 } 533 + 534 + if (buf_size < img_size) { 535 + DRM_ERROR("size of buffers(%lu) is smaller than image(%lu)\n", 536 + buf_size, img_size); 537 + return -EINVAL; 538 + } 539 + 487 540 return 0; 488 541 } 489 542
+490
drivers/gpu/drm/exynos/exynos_drm_mic.c
··· 1 + /* 2 + * Copyright (C) 2015 Samsung Electronics Co.Ltd 3 + * Authors: 4 + * Hyungwon Hwang <human.hwang@samsung.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundationr 9 + */ 10 + 11 + #include <linux/platform_device.h> 12 + #include <video/of_videomode.h> 13 + #include <linux/of_address.h> 14 + #include <video/videomode.h> 15 + #include <linux/module.h> 16 + #include <linux/delay.h> 17 + #include <linux/mutex.h> 18 + #include <linux/of.h> 19 + #include <linux/of_graph.h> 20 + #include <linux/clk.h> 21 + #include <drm/drmP.h> 22 + #include <linux/mfd/syscon.h> 23 + #include <linux/regmap.h> 24 + 25 + /* Sysreg registers for MIC */ 26 + #define DSD_CFG_MUX 0x1004 27 + #define MIC0_RGB_MUX (1 << 0) 28 + #define MIC0_I80_MUX (1 << 1) 29 + #define MIC0_ON_MUX (1 << 5) 30 + 31 + /* MIC registers */ 32 + #define MIC_OP 0x0 33 + #define MIC_IP_VER 0x0004 34 + #define MIC_V_TIMING_0 0x0008 35 + #define MIC_V_TIMING_1 0x000C 36 + #define MIC_IMG_SIZE 0x0010 37 + #define MIC_INPUT_TIMING_0 0x0014 38 + #define MIC_INPUT_TIMING_1 0x0018 39 + #define MIC_2D_OUTPUT_TIMING_0 0x001C 40 + #define MIC_2D_OUTPUT_TIMING_1 0x0020 41 + #define MIC_2D_OUTPUT_TIMING_2 0x0024 42 + #define MIC_3D_OUTPUT_TIMING_0 0x0028 43 + #define MIC_3D_OUTPUT_TIMING_1 0x002C 44 + #define MIC_3D_OUTPUT_TIMING_2 0x0030 45 + #define MIC_CORE_PARA_0 0x0034 46 + #define MIC_CORE_PARA_1 0x0038 47 + #define MIC_CTC_CTRL 0x0040 48 + #define MIC_RD_DATA 0x0044 49 + 50 + #define MIC_UPD_REG (1 << 31) 51 + #define MIC_ON_REG (1 << 30) 52 + #define MIC_TD_ON_REG (1 << 29) 53 + #define MIC_BS_CHG_OUT (1 << 16) 54 + #define MIC_VIDEO_TYPE(x) (((x) & 0xf) << 12) 55 + #define MIC_PSR_EN (1 << 5) 56 + #define MIC_SW_RST (1 << 4) 57 + #define MIC_ALL_RST (1 << 3) 58 + #define MIC_CORE_VER_CONTROL (1 << 2) 59 + #define MIC_MODE_SEL_COMMAND_MODE (1 << 1) 60 + #define MIC_MODE_SEL_MASK (1 << 1) 61 + #define MIC_CORE_EN (1 << 0) 62 + 63 + #define MIC_V_PULSE_WIDTH(x) (((x) & 0x3fff) << 16) 64 + #define MIC_V_PERIOD_LINE(x) ((x) & 0x3fff) 65 + 66 + #define MIC_VBP_SIZE(x) (((x) & 0x3fff) << 16) 67 + #define MIC_VFP_SIZE(x) ((x) & 0x3fff) 68 + 69 + #define MIC_IMG_V_SIZE(x) (((x) & 0x3fff) << 16) 70 + #define MIC_IMG_H_SIZE(x) ((x) & 0x3fff) 71 + 72 + #define MIC_H_PULSE_WIDTH_IN(x) (((x) & 0x3fff) << 16) 73 + #define MIC_H_PERIOD_PIXEL_IN(x) ((x) & 0x3fff) 74 + 75 + #define MIC_HBP_SIZE_IN(x) (((x) & 0x3fff) << 16) 76 + #define MIC_HFP_SIZE_IN(x) ((x) & 0x3fff) 77 + 78 + #define MIC_H_PULSE_WIDTH_2D(x) (((x) & 0x3fff) << 16) 79 + #define MIC_H_PERIOD_PIXEL_2D(x) ((x) & 0x3fff) 80 + 81 + #define MIC_HBP_SIZE_2D(x) (((x) & 0x3fff) << 16) 82 + #define MIC_HFP_SIZE_2D(x) ((x) & 0x3fff) 83 + 84 + #define MIC_BS_SIZE_2D(x) ((x) & 0x3fff) 85 + 86 + enum { 87 + ENDPOINT_DECON_NODE, 88 + ENDPOINT_DSI_NODE, 89 + NUM_ENDPOINTS 90 + }; 91 + 92 + static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; 93 + #define NUM_CLKS ARRAY_SIZE(clk_names) 94 + static DEFINE_MUTEX(mic_mutex); 95 + 96 + struct exynos_mic { 97 + struct device *dev; 98 + void __iomem *reg; 99 + struct regmap *sysreg; 100 + struct clk *clks[NUM_CLKS]; 101 + 102 + bool i80_mode; 103 + struct videomode vm; 104 + struct drm_encoder *encoder; 105 + struct drm_bridge bridge; 106 + 107 + bool enabled; 108 + }; 109 + 110 + static void mic_set_path(struct exynos_mic *mic, bool enable) 111 + { 112 + int ret; 113 + unsigned int val; 114 + 115 + ret = regmap_read(mic->sysreg, DSD_CFG_MUX, &val); 116 + if (ret) { 117 + DRM_ERROR("mic: Failed to read system register\n"); 118 + return; 119 + } 120 + 121 + if (enable) { 122 + if (mic->i80_mode) 123 + val |= MIC0_I80_MUX; 124 + else 125 + val |= MIC0_RGB_MUX; 126 + 127 + val |= MIC0_ON_MUX; 128 + } else 129 + val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); 130 + 131 + regmap_write(mic->sysreg, DSD_CFG_MUX, val); 132 + if (ret) 133 + DRM_ERROR("mic: Failed to read system register\n"); 134 + } 135 + 136 + static int mic_sw_reset(struct exynos_mic *mic) 137 + { 138 + unsigned int retry = 100; 139 + int ret; 140 + 141 + writel(MIC_SW_RST, mic->reg + MIC_OP); 142 + 143 + while (retry-- > 0) { 144 + ret = readl(mic->reg + MIC_OP); 145 + if (!(ret & MIC_SW_RST)) 146 + return 0; 147 + 148 + udelay(10); 149 + } 150 + 151 + return -ETIMEDOUT; 152 + } 153 + 154 + static void mic_set_porch_timing(struct exynos_mic *mic) 155 + { 156 + struct videomode vm = mic->vm; 157 + u32 reg; 158 + 159 + reg = MIC_V_PULSE_WIDTH(vm.vsync_len) + 160 + MIC_V_PERIOD_LINE(vm.vsync_len + vm.vactive + 161 + vm.vback_porch + vm.vfront_porch); 162 + writel(reg, mic->reg + MIC_V_TIMING_0); 163 + 164 + reg = MIC_VBP_SIZE(vm.vback_porch) + 165 + MIC_VFP_SIZE(vm.vfront_porch); 166 + writel(reg, mic->reg + MIC_V_TIMING_1); 167 + 168 + reg = MIC_V_PULSE_WIDTH(vm.hsync_len) + 169 + MIC_V_PERIOD_LINE(vm.hsync_len + vm.hactive + 170 + vm.hback_porch + vm.hfront_porch); 171 + writel(reg, mic->reg + MIC_INPUT_TIMING_0); 172 + 173 + reg = MIC_VBP_SIZE(vm.hback_porch) + 174 + MIC_VFP_SIZE(vm.hfront_porch); 175 + writel(reg, mic->reg + MIC_INPUT_TIMING_1); 176 + } 177 + 178 + static void mic_set_img_size(struct exynos_mic *mic) 179 + { 180 + struct videomode *vm = &mic->vm; 181 + u32 reg; 182 + 183 + reg = MIC_IMG_H_SIZE(vm->hactive) + 184 + MIC_IMG_V_SIZE(vm->vactive); 185 + 186 + writel(reg, mic->reg + MIC_IMG_SIZE); 187 + } 188 + 189 + static void mic_set_output_timing(struct exynos_mic *mic) 190 + { 191 + struct videomode vm = mic->vm; 192 + u32 reg, bs_size_2d; 193 + 194 + DRM_DEBUG("w: %u, h: %u\n", vm.hactive, vm.vactive); 195 + bs_size_2d = ((vm.hactive >> 2) << 1) + (vm.vactive % 4); 196 + reg = MIC_BS_SIZE_2D(bs_size_2d); 197 + writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_2); 198 + 199 + if (!mic->i80_mode) { 200 + reg = MIC_H_PULSE_WIDTH_2D(vm.hsync_len) + 201 + MIC_H_PERIOD_PIXEL_2D(vm.hsync_len + bs_size_2d + 202 + vm.hback_porch + vm.hfront_porch); 203 + writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_0); 204 + 205 + reg = MIC_HBP_SIZE_2D(vm.hback_porch) + 206 + MIC_H_PERIOD_PIXEL_2D(vm.hfront_porch); 207 + writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_1); 208 + } 209 + } 210 + 211 + static void mic_set_reg_on(struct exynos_mic *mic, bool enable) 212 + { 213 + u32 reg = readl(mic->reg + MIC_OP); 214 + 215 + if (enable) { 216 + reg &= ~(MIC_MODE_SEL_MASK | MIC_CORE_VER_CONTROL | MIC_PSR_EN); 217 + reg |= (MIC_CORE_EN | MIC_BS_CHG_OUT | MIC_ON_REG); 218 + 219 + reg &= ~MIC_MODE_SEL_COMMAND_MODE; 220 + if (mic->i80_mode) 221 + reg |= MIC_MODE_SEL_COMMAND_MODE; 222 + } else { 223 + reg &= ~MIC_CORE_EN; 224 + } 225 + 226 + reg |= MIC_UPD_REG; 227 + writel(reg, mic->reg + MIC_OP); 228 + } 229 + 230 + static struct device_node *get_remote_node(struct device_node *from, int reg) 231 + { 232 + struct device_node *endpoint = NULL, *remote_node = NULL; 233 + 234 + endpoint = of_graph_get_endpoint_by_regs(from, reg, -1); 235 + if (!endpoint) { 236 + DRM_ERROR("mic: Failed to find remote port from %s", 237 + from->full_name); 238 + goto exit; 239 + } 240 + 241 + remote_node = of_graph_get_remote_port_parent(endpoint); 242 + if (!remote_node) { 243 + DRM_ERROR("mic: Failed to find remote port parent from %s", 244 + from->full_name); 245 + goto exit; 246 + } 247 + 248 + exit: 249 + of_node_put(endpoint); 250 + return remote_node; 251 + } 252 + 253 + static int parse_dt(struct exynos_mic *mic) 254 + { 255 + int ret = 0, i, j; 256 + struct device_node *remote_node; 257 + struct device_node *nodes[3]; 258 + 259 + /* 260 + * The order of endpoints does matter. 261 + * The first node must be for decon and the second one must be for dsi. 262 + */ 263 + for (i = 0, j = 0; i < NUM_ENDPOINTS; i++) { 264 + remote_node = get_remote_node(mic->dev->of_node, i); 265 + if (!remote_node) { 266 + ret = -EPIPE; 267 + goto exit; 268 + } 269 + nodes[j++] = remote_node; 270 + 271 + switch (i) { 272 + case ENDPOINT_DECON_NODE: 273 + /* decon node */ 274 + if (of_get_child_by_name(remote_node, 275 + "i80-if-timings")) 276 + mic->i80_mode = 1; 277 + 278 + break; 279 + case ENDPOINT_DSI_NODE: 280 + /* panel node */ 281 + remote_node = get_remote_node(remote_node, 1); 282 + if (!remote_node) { 283 + ret = -EPIPE; 284 + goto exit; 285 + } 286 + nodes[j++] = remote_node; 287 + 288 + ret = of_get_videomode(remote_node, 289 + &mic->vm, 0); 290 + if (ret) { 291 + DRM_ERROR("mic: failed to get videomode"); 292 + goto exit; 293 + } 294 + 295 + break; 296 + default: 297 + DRM_ERROR("mic: Unknown endpoint from MIC"); 298 + break; 299 + } 300 + } 301 + 302 + exit: 303 + while (--j > -1) 304 + of_node_put(nodes[j]); 305 + 306 + return ret; 307 + } 308 + 309 + void mic_disable(struct drm_bridge *bridge) { } 310 + 311 + void mic_post_disable(struct drm_bridge *bridge) 312 + { 313 + struct exynos_mic *mic = bridge->driver_private; 314 + int i; 315 + 316 + mutex_lock(&mic_mutex); 317 + if (!mic->enabled) 318 + goto already_disabled; 319 + 320 + mic_set_path(mic, 0); 321 + 322 + for (i = NUM_CLKS - 1; i > -1; i--) 323 + clk_disable_unprepare(mic->clks[i]); 324 + 325 + mic->enabled = 0; 326 + 327 + already_disabled: 328 + mutex_unlock(&mic_mutex); 329 + } 330 + 331 + void mic_pre_enable(struct drm_bridge *bridge) 332 + { 333 + struct exynos_mic *mic = bridge->driver_private; 334 + int ret, i; 335 + 336 + mutex_lock(&mic_mutex); 337 + if (mic->enabled) 338 + goto already_enabled; 339 + 340 + for (i = 0; i < NUM_CLKS; i++) { 341 + ret = clk_prepare_enable(mic->clks[i]); 342 + if (ret < 0) { 343 + DRM_ERROR("Failed to enable clock (%s)\n", 344 + clk_names[i]); 345 + goto turn_off_clks; 346 + } 347 + } 348 + 349 + mic_set_path(mic, 1); 350 + 351 + ret = mic_sw_reset(mic); 352 + if (ret) { 353 + DRM_ERROR("Failed to reset\n"); 354 + goto turn_off_clks; 355 + } 356 + 357 + if (!mic->i80_mode) 358 + mic_set_porch_timing(mic); 359 + mic_set_img_size(mic); 360 + mic_set_output_timing(mic); 361 + mic_set_reg_on(mic, 1); 362 + mic->enabled = 1; 363 + mutex_unlock(&mic_mutex); 364 + 365 + return; 366 + 367 + turn_off_clks: 368 + while (--i > -1) 369 + clk_disable_unprepare(mic->clks[i]); 370 + already_enabled: 371 + mutex_unlock(&mic_mutex); 372 + } 373 + 374 + void mic_enable(struct drm_bridge *bridge) { } 375 + 376 + void mic_destroy(struct drm_bridge *bridge) 377 + { 378 + struct exynos_mic *mic = bridge->driver_private; 379 + int i; 380 + 381 + mutex_lock(&mic_mutex); 382 + if (!mic->enabled) 383 + goto already_disabled; 384 + 385 + for (i = NUM_CLKS - 1; i > -1; i--) 386 + clk_disable_unprepare(mic->clks[i]); 387 + 388 + already_disabled: 389 + mutex_unlock(&mic_mutex); 390 + } 391 + 392 + struct drm_bridge_funcs mic_bridge_funcs = { 393 + .disable = mic_disable, 394 + .post_disable = mic_post_disable, 395 + .pre_enable = mic_pre_enable, 396 + .enable = mic_enable, 397 + }; 398 + 399 + int exynos_mic_probe(struct platform_device *pdev) 400 + { 401 + struct device *dev = &pdev->dev; 402 + struct exynos_mic *mic; 403 + struct resource res; 404 + int ret, i; 405 + 406 + mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL); 407 + if (!mic) { 408 + DRM_ERROR("mic: Failed to allocate memory for MIC object\n"); 409 + ret = -ENOMEM; 410 + goto err; 411 + } 412 + 413 + mic->dev = dev; 414 + 415 + ret = parse_dt(mic); 416 + if (ret) 417 + goto err; 418 + 419 + ret = of_address_to_resource(dev->of_node, 0, &res); 420 + if (ret) { 421 + DRM_ERROR("mic: Failed to get mem region for MIC\n"); 422 + goto err; 423 + } 424 + mic->reg = devm_ioremap(dev, res.start, resource_size(&res)); 425 + if (!mic->reg) { 426 + DRM_ERROR("mic: Failed to remap for MIC\n"); 427 + ret = -ENOMEM; 428 + goto err; 429 + } 430 + 431 + mic->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 432 + "samsung,disp-syscon"); 433 + if (IS_ERR(mic->sysreg)) { 434 + DRM_ERROR("mic: Failed to get system register.\n"); 435 + goto err; 436 + } 437 + 438 + mic->bridge.funcs = &mic_bridge_funcs; 439 + mic->bridge.of_node = dev->of_node; 440 + mic->bridge.driver_private = mic; 441 + ret = drm_bridge_add(&mic->bridge); 442 + if (ret) { 443 + DRM_ERROR("mic: Failed to add MIC to the global bridge list\n"); 444 + goto err; 445 + } 446 + 447 + for (i = 0; i < NUM_CLKS; i++) { 448 + mic->clks[i] = of_clk_get_by_name(dev->of_node, clk_names[i]); 449 + if (IS_ERR(mic->clks[i])) { 450 + DRM_ERROR("mic: Failed to get clock (%s)\n", 451 + clk_names[i]); 452 + ret = PTR_ERR(mic->clks[i]); 453 + goto err; 454 + } 455 + } 456 + 457 + DRM_DEBUG_KMS("MIC has been probed\n"); 458 + 459 + err: 460 + return ret; 461 + } 462 + 463 + static int exynos_mic_remove(struct platform_device *pdev) 464 + { 465 + struct exynos_mic *mic = platform_get_drvdata(pdev); 466 + int i; 467 + 468 + drm_bridge_remove(&mic->bridge); 469 + 470 + for (i = NUM_CLKS - 1; i > -1; i--) 471 + clk_put(mic->clks[i]); 472 + 473 + return 0; 474 + } 475 + 476 + static const struct of_device_id exynos_mic_of_match[] = { 477 + { .compatible = "samsung,exynos5433-mic" }, 478 + { } 479 + }; 480 + MODULE_DEVICE_TABLE(of, exynos_mic_of_match); 481 + 482 + struct platform_driver mic_driver = { 483 + .probe = exynos_mic_probe, 484 + .remove = exynos_mic_remove, 485 + .driver = { 486 + .name = "exynos-mic", 487 + .owner = THIS_MODULE, 488 + .of_match_table = exynos_mic_of_match, 489 + }, 490 + };
+78 -61
drivers/gpu/drm/exynos/exynos_drm_plane.c
··· 13 13 14 14 #include <drm/exynos_drm.h> 15 15 #include <drm/drm_plane_helper.h> 16 + #include <drm/drm_atomic_helper.h> 16 17 #include "exynos_drm_drv.h" 17 18 #include "exynos_drm_crtc.h" 18 19 #include "exynos_drm_fb.h" ··· 62 61 return size; 63 62 } 64 63 65 - int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb) 64 + static void exynos_plane_mode_set(struct drm_plane *plane, 65 + struct drm_crtc *crtc, 66 + struct drm_framebuffer *fb, 67 + int crtc_x, int crtc_y, 68 + unsigned int crtc_w, unsigned int crtc_h, 69 + uint32_t src_x, uint32_t src_y, 70 + uint32_t src_w, uint32_t src_h) 66 71 { 67 72 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 68 - int nr; 69 - int i; 70 - 71 - nr = exynos_drm_fb_get_buf_cnt(fb); 72 - for (i = 0; i < nr; i++) { 73 - struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i); 74 - 75 - if (!buffer) { 76 - DRM_DEBUG_KMS("buffer is null\n"); 77 - return -EFAULT; 78 - } 79 - 80 - exynos_plane->dma_addr[i] = buffer->dma_addr + fb->offsets[i]; 81 - 82 - DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", 83 - i, (unsigned long)exynos_plane->dma_addr[i]); 84 - } 85 - 86 - return 0; 87 - } 88 - 89 - void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, 90 - struct drm_framebuffer *fb, int crtc_x, int crtc_y, 91 - unsigned int crtc_w, unsigned int crtc_h, 92 - uint32_t src_x, uint32_t src_y, 93 - uint32_t src_w, uint32_t src_h) 94 - { 95 - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 73 + struct drm_display_mode *mode = &crtc->state->adjusted_mode; 96 74 unsigned int actual_w; 97 75 unsigned int actual_h; 98 76 99 - actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay); 100 - actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay); 77 + actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay); 78 + actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay); 101 79 102 80 if (crtc_x < 0) { 103 81 if (actual_w) ··· 112 132 exynos_plane->crtc_height = actual_h; 113 133 114 134 /* set drm mode data. */ 115 - exynos_plane->mode_width = crtc->mode.hdisplay; 116 - exynos_plane->mode_height = crtc->mode.vdisplay; 117 - exynos_plane->refresh = crtc->mode.vrefresh; 118 - exynos_plane->scan_flag = crtc->mode.flags; 135 + exynos_plane->mode_width = mode->hdisplay; 136 + exynos_plane->mode_height = mode->vdisplay; 137 + exynos_plane->refresh = mode->vrefresh; 138 + exynos_plane->scan_flag = mode->flags; 119 139 120 140 DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)", 121 141 exynos_plane->crtc_x, exynos_plane->crtc_y, ··· 124 144 plane->crtc = crtc; 125 145 } 126 146 127 - int 128 - exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 129 - struct drm_framebuffer *fb, int crtc_x, int crtc_y, 130 - unsigned int crtc_w, unsigned int crtc_h, 131 - uint32_t src_x, uint32_t src_y, 132 - uint32_t src_w, uint32_t src_h) 147 + static struct drm_plane_funcs exynos_plane_funcs = { 148 + .update_plane = drm_atomic_helper_update_plane, 149 + .disable_plane = drm_atomic_helper_disable_plane, 150 + .destroy = drm_plane_cleanup, 151 + .reset = drm_atomic_helper_plane_reset, 152 + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 153 + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 154 + }; 155 + 156 + static int exynos_plane_atomic_check(struct drm_plane *plane, 157 + struct drm_plane_state *state) 133 158 { 134 - 135 - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 136 159 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 137 - int ret; 160 + int nr; 161 + int i; 138 162 139 - ret = exynos_check_plane(plane, fb); 140 - if (ret < 0) 141 - return ret; 163 + if (!state->fb) 164 + return 0; 142 165 143 - exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, 144 - crtc_w, crtc_h, src_x >> 16, src_y >> 16, 145 - src_w >> 16, src_h >> 16); 166 + nr = exynos_drm_fb_get_buf_cnt(state->fb); 167 + for (i = 0; i < nr; i++) { 168 + struct exynos_drm_gem_buf *buffer = 169 + exynos_drm_fb_buffer(state->fb, i); 170 + 171 + if (!buffer) { 172 + DRM_DEBUG_KMS("buffer is null\n"); 173 + return -EFAULT; 174 + } 175 + 176 + exynos_plane->dma_addr[i] = buffer->dma_addr + 177 + state->fb->offsets[i]; 178 + 179 + DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", 180 + i, (unsigned long)exynos_plane->dma_addr[i]); 181 + } 182 + 183 + return 0; 184 + } 185 + 186 + static void exynos_plane_atomic_update(struct drm_plane *plane, 187 + struct drm_plane_state *old_state) 188 + { 189 + struct drm_plane_state *state = plane->state; 190 + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(state->crtc); 191 + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 192 + 193 + if (!state->crtc) 194 + return; 195 + 196 + exynos_plane_mode_set(plane, state->crtc, state->fb, 197 + state->crtc_x, state->crtc_y, 198 + state->crtc_w, state->crtc_h, 199 + state->src_x >> 16, state->src_y >> 16, 200 + state->src_w >> 16, state->src_h >> 16); 146 201 147 202 if (exynos_crtc->ops->win_commit) 148 203 exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); 149 - 150 - return 0; 151 204 } 152 205 153 - static int exynos_disable_plane(struct drm_plane *plane) 206 + static void exynos_plane_atomic_disable(struct drm_plane *plane, 207 + struct drm_plane_state *old_state) 154 208 { 155 209 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 156 - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc); 210 + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(old_state->crtc); 157 211 158 - if (exynos_crtc && exynos_crtc->ops->win_disable) 212 + if (!old_state->crtc) 213 + return; 214 + 215 + if (exynos_crtc->ops->win_disable) 159 216 exynos_crtc->ops->win_disable(exynos_crtc, 160 217 exynos_plane->zpos); 161 - 162 - return 0; 163 218 } 164 219 165 - static struct drm_plane_funcs exynos_plane_funcs = { 166 - .update_plane = exynos_update_plane, 167 - .disable_plane = exynos_disable_plane, 168 - .destroy = drm_plane_cleanup, 220 + static const struct drm_plane_helper_funcs plane_helper_funcs = { 221 + .atomic_check = exynos_plane_atomic_check, 222 + .atomic_update = exynos_plane_atomic_update, 223 + .atomic_disable = exynos_plane_atomic_disable, 169 224 }; 170 225 171 226 static void exynos_plane_attach_zpos_property(struct drm_plane *plane, ··· 237 222 DRM_ERROR("failed to initialize plane\n"); 238 223 return err; 239 224 } 225 + 226 + drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs); 240 227 241 228 exynos_plane->zpos = zpos; 242 229
-11
drivers/gpu/drm/exynos/exynos_drm_plane.h
··· 9 9 * 10 10 */ 11 11 12 - int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb); 13 - void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, 14 - struct drm_framebuffer *fb, int crtc_x, int crtc_y, 15 - unsigned int crtc_w, unsigned int crtc_h, 16 - uint32_t src_x, uint32_t src_y, 17 - uint32_t src_w, uint32_t src_h); 18 - int exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 19 - struct drm_framebuffer *fb, int crtc_x, int crtc_y, 20 - unsigned int crtc_w, unsigned int crtc_h, 21 - uint32_t src_x, uint32_t src_y, 22 - uint32_t src_w, uint32_t src_h); 23 12 int exynos_plane_init(struct drm_device *dev, 24 13 struct exynos_drm_plane *exynos_plane, 25 14 unsigned long possible_crtcs, enum drm_plane_type type,
+25 -116
drivers/gpu/drm/exynos/exynos_drm_vidi.c
··· 20 20 21 21 #include <drm/drm_edid.h> 22 22 #include <drm/drm_crtc_helper.h> 23 + #include <drm/drm_atomic_helper.h> 23 24 24 25 #include "exynos_drm_drv.h" 25 26 #include "exynos_drm_crtc.h" ··· 131 130 132 131 plane = &ctx->planes[win]; 133 132 134 - plane->enabled = true; 135 - 136 133 DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr); 137 134 138 135 if (ctx->vblank_on) 139 136 schedule_work(&ctx->work); 140 137 } 141 138 142 - static void vidi_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) 139 + static void vidi_enable(struct exynos_drm_crtc *crtc) 143 140 { 144 141 struct vidi_context *ctx = crtc->ctx; 145 - struct exynos_drm_plane *plane; 146 - 147 - if (win < 0 || win >= WINDOWS_NR) 148 - return; 149 - 150 - plane = &ctx->planes[win]; 151 - plane->enabled = false; 152 - 153 - /* TODO. */ 154 - } 155 - 156 - static int vidi_power_on(struct vidi_context *ctx, bool enable) 157 - { 158 - struct exynos_drm_plane *plane; 159 - int i; 160 - 161 - DRM_DEBUG_KMS("%s\n", __FILE__); 162 - 163 - if (enable != false && enable != true) 164 - return -EINVAL; 165 - 166 - if (enable) { 167 - ctx->suspended = false; 168 - 169 - /* if vblank was enabled status, enable it again. */ 170 - if (test_and_clear_bit(0, &ctx->irq_flags)) 171 - vidi_enable_vblank(ctx->crtc); 172 - 173 - for (i = 0; i < WINDOWS_NR; i++) { 174 - plane = &ctx->planes[i]; 175 - if (plane->enabled) 176 - vidi_win_commit(ctx->crtc, i); 177 - } 178 - } else { 179 - ctx->suspended = true; 180 - } 181 - 182 - return 0; 183 - } 184 - 185 - static void vidi_dpms(struct exynos_drm_crtc *crtc, int mode) 186 - { 187 - struct vidi_context *ctx = crtc->ctx; 188 - 189 - DRM_DEBUG_KMS("%d\n", mode); 190 142 191 143 mutex_lock(&ctx->lock); 192 144 193 - switch (mode) { 194 - case DRM_MODE_DPMS_ON: 195 - vidi_power_on(ctx, true); 196 - break; 197 - case DRM_MODE_DPMS_STANDBY: 198 - case DRM_MODE_DPMS_SUSPEND: 199 - case DRM_MODE_DPMS_OFF: 200 - vidi_power_on(ctx, false); 201 - break; 202 - default: 203 - DRM_DEBUG_KMS("unspecified mode %d\n", mode); 204 - break; 205 - } 145 + ctx->suspended = false; 146 + 147 + /* if vblank was enabled status, enable it again. */ 148 + if (test_and_clear_bit(0, &ctx->irq_flags)) 149 + vidi_enable_vblank(ctx->crtc); 150 + 151 + mutex_unlock(&ctx->lock); 152 + } 153 + 154 + static void vidi_disable(struct exynos_drm_crtc *crtc) 155 + { 156 + struct vidi_context *ctx = crtc->ctx; 157 + 158 + mutex_lock(&ctx->lock); 159 + 160 + ctx->suspended = true; 206 161 207 162 mutex_unlock(&ctx->lock); 208 163 } ··· 175 218 } 176 219 177 220 static const struct exynos_drm_crtc_ops vidi_crtc_ops = { 178 - .dpms = vidi_dpms, 221 + .enable = vidi_enable, 222 + .disable = vidi_disable, 179 223 .enable_vblank = vidi_enable_vblank, 180 224 .disable_vblank = vidi_disable_vblank, 181 225 .win_commit = vidi_win_commit, 182 - .win_disable = vidi_win_disable, 183 226 }; 184 227 185 228 static void vidi_fake_vblank_handler(struct work_struct *work) ··· 341 384 } 342 385 343 386 static struct drm_connector_funcs vidi_connector_funcs = { 344 - .dpms = drm_helper_connector_dpms, 387 + .dpms = drm_atomic_helper_connector_dpms, 345 388 .fill_modes = drm_helper_probe_single_connector_modes, 346 389 .detect = vidi_detect, 347 390 .destroy = vidi_connector_destroy, 391 + .reset = drm_atomic_helper_connector_reset, 392 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 393 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 348 394 }; 349 395 350 396 static int vidi_get_modes(struct drm_connector *connector) ··· 480 520 ctx->default_win = 0; 481 521 ctx->pdev = pdev; 482 522 483 - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 484 - EXYNOS_DISPLAY_TYPE_VIDI); 485 - if (ret) 486 - return ret; 487 - 488 - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, 489 - ctx->display.type); 490 - if (ret) 491 - goto err_del_crtc_component; 492 - 493 523 INIT_WORK(&ctx->work, vidi_fake_vblank_handler); 494 524 495 525 mutex_init(&ctx->lock); ··· 489 539 ret = device_create_file(&pdev->dev, &dev_attr_connection); 490 540 if (ret < 0) { 491 541 DRM_ERROR("failed to create connection sysfs.\n"); 492 - goto err_del_conn_component; 542 + return ret; 493 543 } 494 544 495 545 ret = component_add(&pdev->dev, &vidi_component_ops); ··· 500 550 501 551 err_remove_file: 502 552 device_remove_file(&pdev->dev, &dev_attr_connection); 503 - err_del_conn_component: 504 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 505 - err_del_crtc_component: 506 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 507 553 508 554 return ret; 509 555 } ··· 516 570 } 517 571 518 572 component_del(&pdev->dev, &vidi_component_ops); 519 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 520 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 521 573 522 574 return 0; 523 575 } ··· 528 584 .owner = THIS_MODULE, 529 585 }, 530 586 }; 531 - 532 - int exynos_drm_probe_vidi(void) 533 - { 534 - struct platform_device *pdev; 535 - int ret; 536 - 537 - pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0); 538 - if (IS_ERR(pdev)) 539 - return PTR_ERR(pdev); 540 - 541 - ret = platform_driver_register(&vidi_driver); 542 - if (ret) { 543 - platform_device_unregister(pdev); 544 - return ret; 545 - } 546 - 547 - return ret; 548 - } 549 - 550 - static int exynos_drm_remove_vidi_device(struct device *dev, void *data) 551 - { 552 - platform_device_unregister(to_platform_device(dev)); 553 - 554 - return 0; 555 - } 556 - 557 - void exynos_drm_remove_vidi(void) 558 - { 559 - int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL, 560 - exynos_drm_remove_vidi_device); 561 - /* silence compiler warning */ 562 - (void)ret; 563 - 564 - platform_driver_unregister(&vidi_driver); 565 - }
+12 -20
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 17 17 #include <drm/drmP.h> 18 18 #include <drm/drm_edid.h> 19 19 #include <drm/drm_crtc_helper.h> 20 + #include <drm/drm_atomic_helper.h> 20 21 21 22 #include "regs-hdmi.h" 22 23 ··· 1051 1050 } 1052 1051 1053 1052 static struct drm_connector_funcs hdmi_connector_funcs = { 1054 - .dpms = drm_helper_connector_dpms, 1053 + .dpms = drm_atomic_helper_connector_dpms, 1055 1054 .fill_modes = drm_helper_probe_single_connector_modes, 1056 1055 .detect = hdmi_detect, 1057 1056 .destroy = hdmi_connector_destroy, 1057 + .reset = drm_atomic_helper_connector_reset, 1058 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1059 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1058 1060 }; 1059 1061 1060 1062 static int hdmi_get_modes(struct drm_connector *connector) ··· 2127 2123 */ 2128 2124 if (crtc) 2129 2125 funcs = crtc->helper_private; 2130 - if (funcs && funcs->dpms) 2131 - (*funcs->dpms)(crtc, mode); 2126 + if (funcs && funcs->disable) 2127 + (*funcs->disable)(crtc); 2132 2128 2133 2129 hdmi_poweroff(hdata); 2134 2130 break; ··· 2360 2356 hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI; 2361 2357 hdata->display.ops = &hdmi_display_ops; 2362 2358 2363 - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, 2364 - hdata->display.type); 2365 - if (ret) 2366 - return ret; 2367 - 2368 2359 mutex_init(&hdata->hdmi_mutex); 2369 2360 2370 2361 platform_set_drvdata(pdev, hdata); 2371 2362 2372 2363 match = of_match_node(hdmi_match_types, dev->of_node); 2373 - if (!match) { 2374 - ret = -ENODEV; 2375 - goto err_del_component; 2376 - } 2364 + if (!match) 2365 + return -ENODEV; 2377 2366 2378 2367 drv_data = (struct hdmi_driver_data *)match->data; 2379 2368 hdata->type = drv_data->type; ··· 2386 2389 hdata->regs = devm_ioremap_resource(dev, res); 2387 2390 if (IS_ERR(hdata->regs)) { 2388 2391 ret = PTR_ERR(hdata->regs); 2389 - goto err_del_component; 2392 + return ret; 2390 2393 } 2391 2394 2392 2395 ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD"); 2393 2396 if (ret) { 2394 2397 DRM_ERROR("failed to request HPD gpio\n"); 2395 - goto err_del_component; 2398 + return ret; 2396 2399 } 2397 2400 2398 2401 ddc_node = hdmi_legacy_ddc_dt_binding(dev); ··· 2403 2406 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); 2404 2407 if (!ddc_node) { 2405 2408 DRM_ERROR("Failed to find ddc node in device tree\n"); 2406 - ret = -ENODEV; 2407 - goto err_del_component; 2409 + return -ENODEV; 2408 2410 } 2409 2411 2410 2412 out_get_ddc_adpt: ··· 2487 2491 err_ddc: 2488 2492 put_device(&hdata->ddc_adpt->dev); 2489 2493 2490 - err_del_component: 2491 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 2492 - 2493 2494 return ret; 2494 2495 } 2495 2496 ··· 2506 2513 pm_runtime_disable(&pdev->dev); 2507 2514 component_del(&pdev->dev, &hdmi_component_ops); 2508 2515 2509 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); 2510 2516 return 0; 2511 2517 } 2512 2518
+43 -75
drivers/gpu/drm/exynos/exynos_mixer.c
··· 882 882 } 883 883 } 884 884 885 - if (!is_drm_iommu_supported(mixer_ctx->drm_dev)) 886 - return 0; 885 + ret = drm_iommu_attach_device_if_possible(mixer_ctx->crtc, drm_dev, 886 + mixer_ctx->dev); 887 + if (ret) 888 + priv->pipe--; 887 889 888 - return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 890 + return ret; 889 891 } 890 892 891 893 static void mixer_ctx_remove(struct mixer_context *mixer_ctx) ··· 939 937 vp_video_buffer(mixer_ctx, win); 940 938 else 941 939 mixer_graph_buffer(mixer_ctx, win); 942 - 943 - mixer_ctx->planes[win].enabled = true; 944 940 } 945 941 946 942 static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) ··· 952 952 mutex_lock(&mixer_ctx->mixer_mutex); 953 953 if (!mixer_ctx->powered) { 954 954 mutex_unlock(&mixer_ctx->mixer_mutex); 955 - mixer_ctx->planes[win].resume = false; 956 955 return; 957 956 } 958 957 mutex_unlock(&mixer_ctx->mixer_mutex); ··· 963 964 964 965 mixer_vsync_set_update(mixer_ctx, true); 965 966 spin_unlock_irqrestore(&res->reg_slock, flags); 966 - 967 - mixer_ctx->planes[win].enabled = false; 968 967 } 969 968 970 969 static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) ··· 997 1000 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe); 998 1001 } 999 1002 1000 - static void mixer_window_suspend(struct mixer_context *ctx) 1003 + static void mixer_enable(struct exynos_drm_crtc *crtc) 1001 1004 { 1002 - struct exynos_drm_plane *plane; 1003 - int i; 1004 - 1005 - for (i = 0; i < MIXER_WIN_NR; i++) { 1006 - plane = &ctx->planes[i]; 1007 - plane->resume = plane->enabled; 1008 - mixer_win_disable(ctx->crtc, i); 1009 - } 1010 - mixer_wait_for_vblank(ctx->crtc); 1011 - } 1012 - 1013 - static void mixer_window_resume(struct mixer_context *ctx) 1014 - { 1015 - struct exynos_drm_plane *plane; 1016 - int i; 1017 - 1018 - for (i = 0; i < MIXER_WIN_NR; i++) { 1019 - plane = &ctx->planes[i]; 1020 - plane->enabled = plane->resume; 1021 - plane->resume = false; 1022 - if (plane->enabled) 1023 - mixer_win_commit(ctx->crtc, i); 1024 - } 1025 - } 1026 - 1027 - static void mixer_poweron(struct mixer_context *ctx) 1028 - { 1005 + struct mixer_context *ctx = crtc->ctx; 1029 1006 struct mixer_resources *res = &ctx->mixer_res; 1007 + int ret; 1030 1008 1031 1009 mutex_lock(&ctx->mixer_mutex); 1032 1010 if (ctx->powered) { ··· 1013 1041 1014 1042 pm_runtime_get_sync(ctx->dev); 1015 1043 1016 - clk_prepare_enable(res->mixer); 1017 - clk_prepare_enable(res->hdmi); 1044 + ret = clk_prepare_enable(res->mixer); 1045 + if (ret < 0) { 1046 + DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret); 1047 + return; 1048 + } 1049 + ret = clk_prepare_enable(res->hdmi); 1050 + if (ret < 0) { 1051 + DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); 1052 + return; 1053 + } 1018 1054 if (ctx->vp_enabled) { 1019 - clk_prepare_enable(res->vp); 1020 - if (ctx->has_sclk) 1021 - clk_prepare_enable(res->sclk_mixer); 1055 + ret = clk_prepare_enable(res->vp); 1056 + if (ret < 0) { 1057 + DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n", 1058 + ret); 1059 + return; 1060 + } 1061 + if (ctx->has_sclk) { 1062 + ret = clk_prepare_enable(res->sclk_mixer); 1063 + if (ret < 0) { 1064 + DRM_ERROR("Failed to prepare_enable the " \ 1065 + "sclk_mixer clk [%d]\n", 1066 + ret); 1067 + return; 1068 + } 1069 + } 1022 1070 } 1023 1071 1024 1072 mutex_lock(&ctx->mixer_mutex); ··· 1049 1057 1050 1058 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 1051 1059 mixer_win_reset(ctx); 1052 - 1053 - mixer_window_resume(ctx); 1054 1060 } 1055 1061 1056 - static void mixer_poweroff(struct mixer_context *ctx) 1062 + static void mixer_disable(struct exynos_drm_crtc *crtc) 1057 1063 { 1064 + struct mixer_context *ctx = crtc->ctx; 1058 1065 struct mixer_resources *res = &ctx->mixer_res; 1066 + int i; 1059 1067 1060 1068 mutex_lock(&ctx->mixer_mutex); 1061 1069 if (!ctx->powered) { ··· 1066 1074 1067 1075 mixer_stop(ctx); 1068 1076 mixer_regs_dump(ctx); 1069 - mixer_window_suspend(ctx); 1077 + 1078 + for (i = 0; i < MIXER_WIN_NR; i++) 1079 + mixer_win_disable(crtc, i); 1070 1080 1071 1081 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 1072 1082 ··· 1085 1091 } 1086 1092 1087 1093 pm_runtime_put_sync(ctx->dev); 1088 - } 1089 - 1090 - static void mixer_dpms(struct exynos_drm_crtc *crtc, int mode) 1091 - { 1092 - switch (mode) { 1093 - case DRM_MODE_DPMS_ON: 1094 - mixer_poweron(crtc->ctx); 1095 - break; 1096 - case DRM_MODE_DPMS_STANDBY: 1097 - case DRM_MODE_DPMS_SUSPEND: 1098 - case DRM_MODE_DPMS_OFF: 1099 - mixer_poweroff(crtc->ctx); 1100 - break; 1101 - default: 1102 - DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 1103 - break; 1104 - } 1105 1094 } 1106 1095 1107 1096 /* Only valid for Mixer version 16.0.33.0 */ ··· 1108 1131 } 1109 1132 1110 1133 static const struct exynos_drm_crtc_ops mixer_crtc_ops = { 1111 - .dpms = mixer_dpms, 1134 + .enable = mixer_enable, 1135 + .disable = mixer_disable, 1112 1136 .enable_vblank = mixer_enable_vblank, 1113 1137 .disable_vblank = mixer_disable_vblank, 1114 1138 .wait_for_vblank = mixer_wait_for_vblank, ··· 1258 1280 1259 1281 platform_set_drvdata(pdev, ctx); 1260 1282 1261 - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 1262 - EXYNOS_DISPLAY_TYPE_HDMI); 1263 - if (ret) 1264 - return ret; 1265 - 1266 1283 ret = component_add(&pdev->dev, &mixer_component_ops); 1267 - if (ret) { 1268 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1269 - return ret; 1270 - } 1271 - 1272 - pm_runtime_enable(dev); 1284 + if (!ret) 1285 + pm_runtime_enable(dev); 1273 1286 1274 1287 return ret; 1275 1288 } ··· 1270 1301 pm_runtime_disable(&pdev->dev); 1271 1302 1272 1303 component_del(&pdev->dev, &mixer_component_ops); 1273 - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1274 1304 1275 1305 return 0; 1276 1306 }
+33
drivers/of/base.c
··· 2233 2233 EXPORT_SYMBOL(of_graph_get_next_endpoint); 2234 2234 2235 2235 /** 2236 + * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers 2237 + * @parent: pointer to the parent device node 2238 + * @port_reg: identifier (value of reg property) of the parent port node 2239 + * @reg: identifier (value of reg property) of the endpoint node 2240 + * 2241 + * Return: An 'endpoint' node pointer which is identified by reg and at the same 2242 + * is the child of a port node identified by port_reg. reg and port_reg are 2243 + * ignored when they are -1. 2244 + */ 2245 + struct device_node *of_graph_get_endpoint_by_regs( 2246 + const struct device_node *parent, int port_reg, int reg) 2247 + { 2248 + struct of_endpoint endpoint; 2249 + struct device_node *node, *prev_node = NULL; 2250 + 2251 + while (1) { 2252 + node = of_graph_get_next_endpoint(parent, prev_node); 2253 + of_node_put(prev_node); 2254 + if (!node) 2255 + break; 2256 + 2257 + of_graph_parse_endpoint(node, &endpoint); 2258 + if (((port_reg == -1) || (endpoint.port == port_reg)) && 2259 + ((reg == -1) || (endpoint.id == reg))) 2260 + return node; 2261 + 2262 + prev_node = node; 2263 + } 2264 + 2265 + return NULL; 2266 + } 2267 + 2268 + /** 2236 2269 * of_graph_get_remote_port_parent() - get remote port's parent node 2237 2270 * @node: pointer to a local endpoint device_node 2238 2271 *
+8
include/linux/of_graph.h
··· 45 45 struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id); 46 46 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, 47 47 struct device_node *previous); 48 + struct device_node *of_graph_get_endpoint_by_regs( 49 + const struct device_node *parent, int port_reg, int reg); 48 50 struct device_node *of_graph_get_remote_port_parent( 49 51 const struct device_node *node); 50 52 struct device_node *of_graph_get_remote_port(const struct device_node *node); ··· 67 65 static inline struct device_node *of_graph_get_next_endpoint( 68 66 const struct device_node *parent, 69 67 struct device_node *previous) 68 + { 69 + return NULL; 70 + } 71 + 72 + struct device_node *of_graph_get_endpoint_by_regs( 73 + const struct device_node *parent, int port_reg, int reg) 70 74 { 71 75 return NULL; 72 76 }
+165
include/video/exynos5433_decon.h
··· 1 + /* 2 + * Copyright (C) 2014 Samsung Electronics Co.Ltd 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundationr 7 + */ 8 + 9 + #ifndef EXYNOS_REGS_DECON_H 10 + #define EXYNOS_REGS_DECON_H 11 + 12 + /* Exynos543X DECON */ 13 + #define DECON_VIDCON0 0x0000 14 + #define DECON_VIDOUTCON0 0x0010 15 + #define DECON_WINCONx(n) (0x0020 + ((n) * 4)) 16 + #define DECON_VIDOSDxH(n) (0x0080 + ((n) * 4)) 17 + #define DECON_SHADOWCON 0x00A0 18 + #define DECON_VIDOSDxA(n) (0x00B0 + ((n) * 0x20)) 19 + #define DECON_VIDOSDxB(n) (0x00B4 + ((n) * 0x20)) 20 + #define DECON_VIDOSDxC(n) (0x00B8 + ((n) * 0x20)) 21 + #define DECON_VIDOSDxD(n) (0x00BC + ((n) * 0x20)) 22 + #define DECON_VIDOSDxE(n) (0x00C0 + ((n) * 0x20)) 23 + #define DECON_VIDW0xADD0B0(n) (0x0150 + ((n) * 0x10)) 24 + #define DECON_VIDW0xADD0B1(n) (0x0154 + ((n) * 0x10)) 25 + #define DECON_VIDW0xADD0B2(n) (0x0158 + ((n) * 0x10)) 26 + #define DECON_VIDW0xADD1B0(n) (0x01A0 + ((n) * 0x10)) 27 + #define DECON_VIDW0xADD1B1(n) (0x01A4 + ((n) * 0x10)) 28 + #define DECON_VIDW0xADD1B2(n) (0x01A8 + ((n) * 0x10)) 29 + #define DECON_VIDW0xADD2(n) (0x0200 + ((n) * 4)) 30 + #define DECON_LOCALxSIZE(n) (0x0214 + ((n) * 4)) 31 + #define DECON_VIDINTCON0 0x0220 32 + #define DECON_VIDINTCON1 0x0224 33 + #define DECON_WxKEYCON0(n) (0x0230 + ((n - 1) * 8)) 34 + #define DECON_WxKEYCON1(n) (0x0234 + ((n - 1) * 8)) 35 + #define DECON_WxKEYALPHA(n) (0x0250 + ((n - 1) * 4)) 36 + #define DECON_WINxMAP(n) (0x0270 + ((n) * 4)) 37 + #define DECON_QOSLUT07_00 0x02C0 38 + #define DECON_QOSLUT15_08 0x02C4 39 + #define DECON_QOSCTRL 0x02C8 40 + #define DECON_BLENDERQx(n) (0x0300 + ((n - 1) * 4)) 41 + #define DECON_BLENDCON 0x0310 42 + #define DECON_OPE_VIDW0xADD0(n) (0x0400 + ((n) * 4)) 43 + #define DECON_OPE_VIDW0xADD1(n) (0x0414 + ((n) * 4)) 44 + #define DECON_FRAMEFIFO_REG7 0x051C 45 + #define DECON_FRAMEFIFO_REG8 0x0520 46 + #define DECON_FRAMEFIFO_STATUS 0x0524 47 + #define DECON_CMU 0x1404 48 + #define DECON_UPDATE 0x1410 49 + #define DECON_UPDATE_SCHEME 0x1438 50 + #define DECON_VIDCON1 0x2000 51 + #define DECON_VIDCON2 0x2004 52 + #define DECON_VIDCON3 0x2008 53 + #define DECON_VIDCON4 0x200C 54 + #define DECON_VIDTCON2 0x2028 55 + #define DECON_FRAME_SIZE 0x2038 56 + #define DECON_LINECNT_OP_THRESHOLD 0x203C 57 + #define DECON_TRIGCON 0x2040 58 + #define DECON_TRIGSKIP 0x2050 59 + #define DECON_CRCRDATA 0x20B0 60 + #define DECON_CRCCTRL 0x20B4 61 + 62 + /* Exynos5430 DECON */ 63 + #define DECON_VIDTCON0 0x2020 64 + #define DECON_VIDTCON1 0x2024 65 + 66 + /* Exynos5433 DECON */ 67 + #define DECON_VIDTCON00 0x2010 68 + #define DECON_VIDTCON01 0x2014 69 + #define DECON_VIDTCON10 0x2018 70 + #define DECON_VIDTCON11 0x201C 71 + 72 + /* Exynos543X DECON Internal */ 73 + #define DECON_W013DSTREOCON 0x0320 74 + #define DECON_W233DSTREOCON 0x0324 75 + #define DECON_FRAMEFIFO_REG0 0x0500 76 + #define DECON_ENHANCER_CTRL 0x2100 77 + 78 + /* Exynos543X DECON TV */ 79 + #define DECON_VCLKCON0 0x0014 80 + #define DECON_VIDINTCON2 0x0228 81 + #define DECON_VIDINTCON3 0x022C 82 + 83 + /* VIDCON0 */ 84 + #define VIDCON0_SWRESET (1 << 28) 85 + #define VIDCON0_STOP_STATUS (1 << 2) 86 + #define VIDCON0_ENVID (1 << 1) 87 + #define VIDCON0_ENVID_F (1 << 0) 88 + 89 + /* VIDOUTCON0 */ 90 + #define VIDOUT_LCD_ON (1 << 24) 91 + #define VIDOUT_IF_F_MASK (0x3 << 20) 92 + #define VIDOUT_RGB_IF (0x0 << 20) 93 + #define VIDOUT_COMMAND_IF (0x2 << 20) 94 + 95 + /* WINCONx */ 96 + #define WINCONx_HAWSWP_F (1 << 16) 97 + #define WINCONx_WSWP_F (1 << 15) 98 + #define WINCONx_BURSTLEN_MASK (0x3 << 10) 99 + #define WINCONx_BURSTLEN_16WORD (0x0 << 10) 100 + #define WINCONx_BURSTLEN_8WORD (0x1 << 10) 101 + #define WINCONx_BURSTLEN_4WORD (0x2 << 10) 102 + #define WINCONx_BLD_PIX_F (1 << 6) 103 + #define WINCONx_BPPMODE_MASK (0xf << 2) 104 + #define WINCONx_BPPMODE_16BPP_565 (0x5 << 2) 105 + #define WINCONx_BPPMODE_16BPP_A1555 (0x6 << 2) 106 + #define WINCONx_BPPMODE_16BPP_I1555 (0x7 << 2) 107 + #define WINCONx_BPPMODE_24BPP_888 (0xb << 2) 108 + #define WINCONx_BPPMODE_24BPP_A1887 (0xc << 2) 109 + #define WINCONx_BPPMODE_25BPP_A1888 (0xd << 2) 110 + #define WINCONx_BPPMODE_32BPP_A8888 (0xd << 2) 111 + #define WINCONx_BPPMODE_16BPP_A4444 (0xe << 2) 112 + #define WINCONx_ALPHA_SEL_F (1 << 1) 113 + #define WINCONx_ENWIN_F (1 << 0) 114 + 115 + /* SHADOWCON */ 116 + #define SHADOWCON_Wx_PROTECT(n) (1 << (10 + (n))) 117 + 118 + /* VIDOSDxD */ 119 + #define VIDOSD_Wx_ALPHA_R_F(n) (((n) & 0xff) << 16) 120 + #define VIDOSD_Wx_ALPHA_G_F(n) (((n) & 0xff) << 8) 121 + #define VIDOSD_Wx_ALPHA_B_F(n) (((n) & 0xff) << 0) 122 + 123 + /* VIDINTCON0 */ 124 + #define VIDINTCON0_FRAMEDONE (1 << 17) 125 + #define VIDINTCON0_INTFRMEN (1 << 12) 126 + #define VIDINTCON0_INTEN (1 << 0) 127 + 128 + /* VIDINTCON1 */ 129 + #define VIDINTCON1_INTFRMDONEPEND (1 << 2) 130 + #define VIDINTCON1_INTFRMPEND (1 << 1) 131 + #define VIDINTCON1_INTFIFOPEND (1 << 0) 132 + 133 + /* DECON_CMU */ 134 + #define CMU_CLKGAGE_MODE_SFR_F (1 << 1) 135 + #define CMU_CLKGAGE_MODE_MEM_F (1 << 0) 136 + 137 + /* DECON_UPDATE */ 138 + #define STANDALONE_UPDATE_F (1 << 0) 139 + 140 + /* DECON_VIDTCON00 */ 141 + #define VIDTCON00_VBPD_F(x) (((x) & 0xfff) << 16) 142 + #define VIDTCON00_VFPD_F(x) ((x) & 0xfff) 143 + 144 + /* DECON_VIDTCON01 */ 145 + #define VIDTCON01_VSPW_F(x) (((x) & 0xfff) << 16) 146 + 147 + /* DECON_VIDTCON10 */ 148 + #define VIDTCON10_HBPD_F(x) (((x) & 0xfff) << 16) 149 + #define VIDTCON10_HFPD_F(x) ((x) & 0xfff) 150 + 151 + /* DECON_VIDTCON11 */ 152 + #define VIDTCON11_HSPW_F(x) (((x) & 0xfff) << 16) 153 + 154 + /* DECON_VIDTCON2 */ 155 + #define VIDTCON2_LINEVAL(x) (((x) & 0xfff) << 16) 156 + #define VIDTCON2_HOZVAL(x) ((x) & 0xfff) 157 + 158 + /* TRIGCON */ 159 + #define TRIGCON_TRIGEN_PER_F (1 << 31) 160 + #define TRIGCON_TRIGEN_F (1 << 30) 161 + #define TRIGCON_TE_AUTO_MASK (1 << 29) 162 + #define TRIGCON_SWTRIGCMD (1 << 1) 163 + #define TRIGCON_SWTRIGEN (1 << 0) 164 + 165 + #endif /* EXYNOS_REGS_DECON_H */