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

Merge tag 'drm-misc-next-2017-09-20' of git://anongit.freedesktop.org/git/drm-misc into drm-next

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
- DP SDP defines (Ville)
- polish for scdc helpers (Thierry Reding)
- fix lifetimes for connector/plane state across crtc changes (Maarten
Lankhorst).
- sparse fixes (Ville+Thierry)
- make legacy kms ioctls all interruptible (Maarten)
- push edid override into the edid helpers (out of probe helpers)
(Jani)
- DP ESI defines for link status (DK)

Driver Changes:
- drm-panel is now in drm-misc!
- minor panel-simple cleanups/refactoring by various folks
- drm_bridge_add cleanup (Inki Dae)
- constify a few i2c_device_id structs (Arvind Yadav)
- More patches from Noralf's fb/gem helper cleanup
- bridge/synopsis: reset fix (Philippe Cornu)
- fix tracepoint include handling in drivers (Thierry)
- rockchip: lvds support (Sandy Huang)
- move sun4i into drm-misc fold (Maxime Ripard)
- sun4i: refactor driver load + support TCON backend/layer muxing
(Chen-Yu Tsai)
- pl111: support more pl11x variants (Linus Walleij)
- bridge/adv7511: robustify probing/edid handling (Lars-Petersen
Clausen)

New hw support:
- S6E63J0X03 panel (Hoegeun Kwon)
- OTM8009A panel (Philippe CORNU)
- Seiko 43WVF1G panel (Marco Franchi)
- tve200 driver (Linus Walleij)

Plus assorted of tiny patches all over, including our first outreachy
patches from applicants for the winter round!

* tag 'drm-misc-next-2017-09-20' of git://anongit.freedesktop.org/git/drm-misc: (101 commits)
drm: add backwards compatibility support for drm_kms_helper.edid_firmware
drm: handle override and firmware EDID at drm_do_get_edid() level
drm/dp: DPCD register defines for link status within ESI field
drm/rockchip: Replace dev_* with DRM_DEV_*
drm/tinydrm: Drop driver registered message
drm/gem-fb-helper: Use debug message on gem lookup failure
drm/imx: Use drm_gem_fb_create() and drm_gem_fb_prepare_fb()
drm/bridge: adv7511: Constify HDMI CODEC platform data
drm/bridge: adv7511: Enable connector polling when no interrupt is specified
drm/bridge: adv7511: Remove private copy of the EDID
drm/bridge: adv7511: Properly update EDID when no EDID was found
drm/crtc: Convert setcrtc ioctl locking to interruptible.
drm/atomic: Convert pageflip ioctl locking to interruptible.
drm/legacy: Convert setplane ioctl locking to interruptible.
drm/legacy: Convert cursor ioctl locking to interruptible.
drm/atomic: Convert atomic ioctl locking to interruptible.
drm/atomic: Prepare drm_modeset_lock infrastructure for interruptible waiting, v2.
drm/tve200: Clean up panel bridging
drm/doc: Update todo.rst
drm/dp/mst: Sideband message transaction to power up/down nodes
...

+4781 -966
+1 -1
Documentation/admin-guide/kernel-parameters.txt
··· 854 854 The filter can be disabled or changed to another 855 855 driver later using sysfs. 856 856 857 - drm_kms_helper.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>] 857 + drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>] 858 858 Broken monitors, graphic adapters, KVMs and EDIDless 859 859 panels may send no or incorrect EDID data sets. 860 860 This parameter allows to specify an EDID data sets
+54
Documentation/devicetree/bindings/display/faraday,tve200.txt
··· 1 + * Faraday TV Encoder TVE200 2 + 3 + Required properties: 4 + 5 + - compatible: must be one of: 6 + "faraday,tve200" 7 + "cortina,gemini-tvc", "faraday,tve200" 8 + 9 + - reg: base address and size of the control registers block 10 + 11 + - interrupts: contains an interrupt specifier for the interrupt 12 + line from the TVE200 13 + 14 + - clock-names: should contain "PCLK" for the clock line clocking the 15 + silicon and "TVE" for the 27MHz clock to the video driver 16 + 17 + - clocks: contains phandle and clock specifier pairs for the entries 18 + in the clock-names property. See 19 + Documentation/devicetree/bindings/clock/clock-bindings.txt 20 + 21 + Optional properties: 22 + 23 + - resets: contains the reset line phandle for the block 24 + 25 + Required sub-nodes: 26 + 27 + - port: describes LCD panel signals, following the common binding 28 + for video transmitter interfaces; see 29 + Documentation/devicetree/bindings/media/video-interfaces.txt 30 + This port should have the properties: 31 + reg = <0>; 32 + It should have one endpoint connected to a remote endpoint where 33 + the display is connected. 34 + 35 + Example: 36 + 37 + display-controller@6a000000 { 38 + #address-cells = <1>; 39 + #size-cells = <0>; 40 + compatible = "faraday,tve200"; 41 + reg = <0x6a000000 0x1000>; 42 + interrupts = <13 IRQ_TYPE_EDGE_RISING>; 43 + resets = <&syscon GEMINI_RESET_TVC>; 44 + clocks = <&syscon GEMINI_CLK_GATE_TVC>, 45 + <&syscon GEMINI_CLK_TVC>; 46 + clock-names = "PCLK", "TVE"; 47 + 48 + port@0 { 49 + reg = <0>; 50 + display_out: endpoint { 51 + remote-endpoint = <&panel_in>; 52 + }; 53 + }; 54 + };
+21
Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
··· 1 + Orise Tech OTM8009A 3.97" 480x800 TFT LCD panel (MIPI-DSI video mode) 2 + 3 + The Orise Tech OTM8009A is a 3.97" 480x800 TFT LCD panel connected using 4 + a MIPI-DSI video interface. Its backlight is managed through the DSI link. 5 + 6 + Required properties: 7 + - compatible: "orisetech,otm8009a" 8 + - reg: the virtual channel number of a DSI peripheral 9 + 10 + Optional properties: 11 + - reset-gpios: a GPIO spec for the reset pin (active low). 12 + 13 + Example: 14 + &dsi { 15 + ... 16 + panel@0 { 17 + compatible = "orisetech,otm8009a"; 18 + reg = <0>; 19 + reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>; 20 + }; 21 + };
+24
Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
··· 1 + Samsung S6E63J0X03 1.63" 320x320 AMOLED panel (interface: MIPI-DSI command mode) 2 + 3 + Required properties: 4 + - compatible: "samsung,s6e63j0x03" 5 + - reg: the virtual channel number of a DSI peripheral 6 + - vdd3-supply: I/O voltage supply 7 + - vci-supply: voltage supply for analog circuits 8 + - reset-gpios: a GPIO spec for the reset pin (active low) 9 + - te-gpios: a GPIO spec for the tearing effect synchronization signal 10 + gpio pin (active high) 11 + 12 + Example: 13 + &dsi { 14 + ... 15 + 16 + panel@0 { 17 + compatible = "samsung,s6e63j0x03"; 18 + reg = <0>; 19 + vdd3-supply = <&ldo16_reg>; 20 + vci-supply = <&ldo20_reg>; 21 + reset-gpios = <&gpe0 1 GPIO_ACTIVE_LOW>; 22 + te-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>; 23 + }; 24 + };
+23
Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
··· 1 + Seiko Instruments Inc. 4.3" WVGA (800 x RGB x 480) TFT with Touch-Panel 2 + 3 + Required properties: 4 + - compatible: should be "sii,43wvf1g". 5 + - "dvdd-supply": 3v3 digital regulator. 6 + - "avdd-supply": 5v analog regulator. 7 + 8 + Optional properties: 9 + - backlight: phandle for the backlight control. 10 + 11 + Example: 12 + 13 + panel { 14 + compatible = "sii,43wvf1g"; 15 + backlight = <&backlight_display>; 16 + dvdd-supply = <&reg_lcd_3v3>; 17 + avdd-supply = <&reg_lcd_5v>; 18 + port { 19 + panel_in: endpoint { 20 + remote-endpoint = <&display_out>; 21 + }; 22 + }; 23 + };
+99
Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt
··· 1 + Rockchip RK3288 LVDS interface 2 + ================================ 3 + 4 + Required properties: 5 + - compatible: matching the soc type, one of 6 + - "rockchip,rk3288-lvds"; 7 + 8 + - reg: physical base address of the controller and length 9 + of memory mapped region. 10 + - clocks: must include clock specifiers corresponding to entries in the 11 + clock-names property. 12 + - clock-names: must contain "pclk_lvds" 13 + 14 + - avdd1v0-supply: regulator phandle for 1.0V analog power 15 + - avdd1v8-supply: regulator phandle for 1.8V analog power 16 + - avdd3v3-supply: regulator phandle for 3.3V analog power 17 + 18 + - rockchip,grf: phandle to the general register files syscon 19 + - rockchip,output: "rgb", "lvds" or "duallvds", This describes the output interface 20 + 21 + Optional properties: 22 + - pinctrl-names: must contain a "lcdc" entry. 23 + - pinctrl-0: pin control group to be used for this controller. 24 + 25 + Required nodes: 26 + 27 + The lvds has two video ports as described by 28 + Documentation/devicetree/bindings/media/video-interfaces.txt 29 + Their connections are modeled using the OF graph bindings specified in 30 + Documentation/devicetree/bindings/graph.txt. 31 + 32 + - video port 0 for the VOP input, the remote endpoint maybe vopb or vopl 33 + - video port 1 for either a panel or subsequent encoder 34 + 35 + the lvds panel described by 36 + Documentation/devicetree/bindings/display/panel/simple-panel.txt 37 + 38 + Panel required properties: 39 + - ports for remote LVDS output 40 + 41 + Panel optional properties: 42 + - data-mapping: should be "vesa-24","jeida-24" or "jeida-18". 43 + This describes decribed by: 44 + Documentation/devicetree/bindings/display/panel/panel-lvds.txt 45 + 46 + Example: 47 + 48 + lvds_panel: lvds-panel { 49 + compatible = "auo,b101ean01"; 50 + enable-gpios = <&gpio7 21 GPIO_ACTIVE_HIGH>; 51 + data-mapping = "jeida-24"; 52 + 53 + ports { 54 + panel_in_lvds: endpoint { 55 + remote-endpoint = <&lvds_out_panel>; 56 + }; 57 + }; 58 + }; 59 + 60 + For Rockchip RK3288: 61 + 62 + lvds: lvds@ff96c000 { 63 + compatible = "rockchip,rk3288-lvds"; 64 + rockchip,grf = <&grf>; 65 + reg = <0xff96c000 0x4000>; 66 + clocks = <&cru PCLK_LVDS_PHY>; 67 + clock-names = "pclk_lvds"; 68 + pinctrl-names = "lcdc"; 69 + pinctrl-0 = <&lcdc_ctl>; 70 + avdd1v0-supply = <&vdd10_lcd>; 71 + avdd1v8-supply = <&vcc18_lcd>; 72 + avdd3v3-supply = <&vcca_33>; 73 + rockchip,output = "rgb"; 74 + ports { 75 + #address-cells = <1>; 76 + #size-cells = <0>; 77 + 78 + lvds_in: port@0 { 79 + reg = <0>; 80 + 81 + lvds_in_vopb: endpoint@0 { 82 + reg = <0>; 83 + remote-endpoint = <&vopb_out_lvds>; 84 + }; 85 + lvds_in_vopl: endpoint@1 { 86 + reg = <1>; 87 + remote-endpoint = <&vopl_out_lvds>; 88 + }; 89 + }; 90 + 91 + lvds_out: port@1 { 92 + reg = <1>; 93 + 94 + lvds_out_panel: endpoint { 95 + remote-endpoint = <&panel_in_lvds>; 96 + }; 97 + }; 98 + }; 99 + };
+1
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 248 248 opencores OpenCores.org 249 249 option Option NV 250 250 ORCL Oracle Corporation 251 + orisetech Orise Technology 251 252 ortustech Ortus Technology Co., Ltd. 252 253 ovti OmniVision Technologies 253 254 oxsemi Oxford Semiconductor, Ltd.
+55
Documentation/gpu/drm-uapi.rst
··· 168 168 .. kernel-doc:: drivers/gpu/drm/drm_ioctl.c 169 169 :doc: driver specific ioctls 170 170 171 + Recommended IOCTL Return Values 172 + ------------------------------- 173 + 174 + In theory a driver's IOCTL callback is only allowed to return very few error 175 + codes. In practice it's good to abuse a few more. This section documents common 176 + practice within the DRM subsystem: 177 + 178 + ENOENT: 179 + Strictly this should only be used when a file doesn't exist e.g. when 180 + calling the open() syscall. We reuse that to signal any kind of object 181 + lookup failure, e.g. for unknown GEM buffer object handles, unknown KMS 182 + object handles and similar cases. 183 + 184 + ENOSPC: 185 + Some drivers use this to differentiate "out of kernel memory" from "out 186 + of VRAM". Sometimes also applies to other limited gpu resources used for 187 + rendering (e.g. when you have a special limited compression buffer). 188 + Sometimes resource allocation/reservation issues in command submission 189 + IOCTLs are also signalled through EDEADLK. 190 + 191 + Simply running out of kernel/system memory is signalled through ENOMEM. 192 + 193 + EPERM/EACCESS: 194 + Returned for an operation that is valid, but needs more privileges. 195 + E.g. root-only or much more common, DRM master-only operations return 196 + this when when called by unpriviledged clients. There's no clear 197 + difference between EACCESS and EPERM. 198 + 199 + ENODEV: 200 + Feature (like PRIME, modesetting, GEM) is not supported by the driver. 201 + 202 + ENXIO: 203 + Remote failure, either a hardware transaction (like i2c), but also used 204 + when the exporting driver of a shared dma-buf or fence doesn't support a 205 + feature needed. 206 + 207 + EINTR: 208 + DRM drivers assume that userspace restarts all IOCTLs. Any DRM IOCTL can 209 + return EINTR and in such a case should be restarted with the IOCTL 210 + parameters left unchanged. 211 + 212 + EIO: 213 + The GPU died and couldn't be resurrected through a reset. Modesetting 214 + hardware failures are signalled through the "link status" connector 215 + property. 216 + 217 + EINVAL: 218 + Catch-all for anything that is an invalid argument combination which 219 + cannot work. 220 + 221 + IOCTL also use other error codes like ETIME, EFAULT, EBUSY, ENOTTY but their 222 + usage is in line with the common meanings. The above list tries to just document 223 + DRM specific patterns. Note that ENOTTY has the slightly unintuitive meaning of 224 + "this IOCTL does not exist", and is used exactly as such in DRM. 225 + 171 226 .. kernel-doc:: include/drm/drm_ioctl.h 172 227 :internal: 173 228
+1
Documentation/gpu/index.rst
··· 15 15 pl111 16 16 tegra 17 17 tinydrm 18 + tve200 18 19 vc4 19 20 vga-switcheroo 20 21 vgaarbiter
+15 -11
Documentation/gpu/todo.rst
··· 75 75 76 76 Contact: Ville Syrjälä, Daniel Vetter, driver maintainers 77 77 78 - Implement deferred fbdev setup in the helper 79 - -------------------------------------------- 80 - 81 - Many (especially embedded drivers) want to delay fbdev setup until there's a 82 - real screen plugged in. This is to avoid the dreaded fallback to the low-res 83 - fbdev default. Many drivers have a hacked-up (and often broken) version of this, 84 - better to do it once in the shared helpers. Thierry has a patch series, but that 85 - one needs to be rebased and final polish applied. 86 - 87 - Contact: Thierry Reding, Daniel Vetter, driver maintainers 88 - 89 78 Convert early atomic drivers to async commit helpers 90 79 ---------------------------------------------------- 91 80 ··· 127 138 the acquire context explicitly on stack and then also pass it down into 128 139 drivers explicitly so that the legacy-on-atomic functions can use them. 129 140 141 + Except for some driver code this is done. 142 + 130 143 * A bunch of the vtable hooks are now in the wrong place: DRM has a split 131 144 between core vfunc tables (named ``drm_foo_funcs``), which are used to 132 145 implement the userspace ABI. And then there's the optional hooks for the ··· 141 150 used by all atomic drivers which don't select the encoder for a given 142 151 connector at runtime. That's almost all of them, and would allow us to get 143 152 rid of a lot of ``best_encoder`` boilerplate in drivers. 153 + 154 + This was almost done, but new drivers added a few more cases again. 144 155 145 156 Contact: Daniel Vetter 146 157 ··· 169 176 ``udl``. 170 177 171 178 Contact: Daniel Vetter, respective driver maintainers 179 + 180 + Convert instances of dev_info/dev_err/dev_warn to their DRM_DEV_* equivalent 181 + ---------------------------------------------------------------------------- 182 + 183 + For drivers which could have multiple instances, it is necessary to 184 + differentiate between which is which in the logs. Since DRM_INFO/WARN/ERROR 185 + don't do this, drivers used dev_info/warn/err to make this differentiation. We 186 + now have DRM_DEV_* variants of the drm print macros, so we can start to convert 187 + those drivers back to using drm-formwatted specific log messages. 188 + 189 + Contact: Sean Paul, Maintainer of the driver you plan to convert 172 190 173 191 Core refactorings 174 192 =================
+6
Documentation/gpu/tve200.rst
··· 1 + ================================== 2 + drm/tve200 Faraday TV Encoder 200 3 + ================================== 4 + 5 + .. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c 6 + :doc: Faraday TV Encoder 200
+8 -2
MAINTAINERS
··· 4366 4366 S: Maintained 4367 4367 F: drivers/gpu/drm/bochs/ 4368 4368 4369 + DRM DRIVER FOR FARADAY TVE200 TV ENCODER 4370 + M: Linus Walleij <linus.walleij@linaro.org> 4371 + T: git git://anongit.freedesktop.org/drm/drm-misc 4372 + S: Maintained 4373 + F: drivers/gpu/drm/tve200/ 4374 + 4369 4375 DRM DRIVER FOR INTEL I810 VIDEO CARDS 4370 4376 S: Orphan / Obsolete 4371 4377 F: drivers/gpu/drm/i810/ ··· 4515 4509 S: Supported 4516 4510 F: drivers/gpu/drm/sun4i/ 4517 4511 F: Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt 4518 - T: git git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git 4512 + T: git git://anongit.freedesktop.org/drm/drm-misc 4519 4513 4520 4514 DRM DRIVERS FOR AMLOGIC SOCS 4521 4515 M: Neil Armstrong <narmstrong@baylibre.com> ··· 4699 4693 DRM PANEL DRIVERS 4700 4694 M: Thierry Reding <thierry.reding@gmail.com> 4701 4695 L: dri-devel@lists.freedesktop.org 4702 - T: git git://anongit.freedesktop.org/tegra/linux.git 4696 + T: git git://anongit.freedesktop.org/drm/drm-misc 4703 4697 S: Maintained 4704 4698 F: drivers/gpu/drm/drm_panel.c 4705 4699 F: drivers/gpu/drm/panel/
+9 -1
drivers/dma-buf/sw_sync.c
··· 321 321 static int sw_sync_debugfs_release(struct inode *inode, struct file *file) 322 322 { 323 323 struct sync_timeline *obj = file->private_data; 324 + struct sync_pt *pt, *next; 324 325 325 - smp_wmb(); 326 + spin_lock_irq(&obj->lock); 327 + 328 + list_for_each_entry_safe(pt, next, &obj->pt_list, link) { 329 + dma_fence_set_error(&pt->base, -ENOENT); 330 + dma_fence_signal_locked(&pt->base); 331 + } 332 + 333 + spin_unlock_irq(&obj->lock); 326 334 327 335 sync_timeline_put(obj); 328 336 return 0;
+3 -1
drivers/gpu/drm/Kconfig
··· 110 110 111 111 config DRM_LOAD_EDID_FIRMWARE 112 112 bool "Allow to specify an EDID data set instead of probing for it" 113 - depends on DRM_KMS_HELPER 113 + depends on DRM 114 114 help 115 115 Say Y here, if you want to use EDID data to be loaded from the 116 116 /lib/firmware directory or one of the provided built-in ··· 277 277 source "drivers/gpu/drm/tinydrm/Kconfig" 278 278 279 279 source "drivers/gpu/drm/pl111/Kconfig" 280 + 281 + source "drivers/gpu/drm/tve200/Kconfig" 280 282 281 283 # Keep legacy drivers last 282 284
+2 -3
drivers/gpu/drm/Makefile
··· 28 28 drm-$(CONFIG_OF) += drm_of.o 29 29 drm-$(CONFIG_AGP) += drm_agpsupport.o 30 30 drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o 31 + drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 31 32 32 33 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 33 34 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ ··· 37 36 drm_scdc_helper.o drm_gem_framebuffer_helper.o 38 37 39 38 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o 40 - drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 41 39 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 42 40 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o 43 41 drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o 44 42 45 43 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o 46 44 obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/ 47 - 48 - CFLAGS_drm_trace_points.o := -I$(src) 49 45 50 46 obj-$(CONFIG_DRM) += drm.o 51 47 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o ··· 98 100 obj-$(CONFIG_DRM_MXSFB) += mxsfb/ 99 101 obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ 100 102 obj-$(CONFIG_DRM_PL111) += pl111/ 103 + obj-$(CONFIG_DRM_TVE200) += tve200/
+2 -1
drivers/gpu/drm/arc/arcpgu_drv.c
··· 18 18 #include <drm/drm_crtc_helper.h> 19 19 #include <drm/drm_fb_cma_helper.h> 20 20 #include <drm/drm_gem_cma_helper.h> 21 + #include <drm/drm_gem_framebuffer_helper.h> 21 22 #include <drm/drm_atomic_helper.h> 22 23 #include <linux/of_reserved_mem.h> 23 24 ··· 33 32 } 34 33 35 34 static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { 36 - .fb_create = drm_fb_cma_create, 35 + .fb_create = drm_gem_fb_create, 37 36 .output_poll_changed = arcpgu_fb_output_poll_changed, 38 37 .atomic_check = drm_atomic_helper_check, 39 38 .atomic_commit = drm_atomic_helper_commit,
+2 -1
drivers/gpu/drm/arm/hdlcd_drv.c
··· 25 25 #include <drm/drm_fb_helper.h> 26 26 #include <drm/drm_fb_cma_helper.h> 27 27 #include <drm/drm_gem_cma_helper.h> 28 + #include <drm/drm_gem_framebuffer_helper.h> 28 29 #include <drm/drm_of.h> 29 30 30 31 #include "hdlcd_drv.h" ··· 107 106 } 108 107 109 108 static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = { 110 - .fb_create = drm_fb_cma_create, 109 + .fb_create = drm_gem_fb_create, 111 110 .output_poll_changed = hdlcd_fb_output_poll_changed, 112 111 .atomic_check = drm_atomic_helper_check, 113 112 .atomic_commit = drm_atomic_helper_commit,
+2 -1
drivers/gpu/drm/arm/malidp_drv.c
··· 26 26 #include <drm/drm_crtc_helper.h> 27 27 #include <drm/drm_fb_cma_helper.h> 28 28 #include <drm/drm_gem_cma_helper.h> 29 + #include <drm/drm_gem_framebuffer_helper.h> 29 30 #include <drm/drm_of.h> 30 31 31 32 #include "malidp_drv.h" ··· 250 249 }; 251 250 252 251 static const struct drm_mode_config_funcs malidp_mode_config_funcs = { 253 - .fb_create = drm_fb_cma_create, 252 + .fb_create = drm_gem_fb_create, 254 253 .output_poll_changed = malidp_output_poll_changed, 255 254 .atomic_check = drm_atomic_helper_check, 256 255 .atomic_commit = drm_atomic_helper_commit,
-2
drivers/gpu/drm/armada/Makefile
··· 4 4 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o 5 5 6 6 obj-$(CONFIG_DRM_ARMADA) := armada.o 7 - 8 - CFLAGS_armada_trace.o := -I$(src)
-2
drivers/gpu/drm/armada/armada_drv.c
··· 70 70 .gem_prime_export = armada_gem_prime_export, 71 71 .gem_prime_import = armada_gem_prime_import, 72 72 .dumb_create = armada_gem_dumb_create, 73 - .dumb_map_offset = armada_gem_dumb_map_offset, 74 - .dumb_destroy = armada_gem_dumb_destroy, 75 73 .gem_vm_ops = &armada_gem_vm_ops, 76 74 .major = 1, 77 75 .minor = 0,
-36
drivers/gpu/drm/armada/armada_gem.c
··· 270 270 return ret; 271 271 } 272 272 273 - int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, 274 - uint32_t handle, uint64_t *offset) 275 - { 276 - struct armada_gem_object *obj; 277 - int ret = 0; 278 - 279 - obj = armada_gem_object_lookup(file, handle); 280 - if (!obj) { 281 - DRM_ERROR("failed to lookup gem object\n"); 282 - return -EINVAL; 283 - } 284 - 285 - /* Don't allow imported objects to be mapped */ 286 - if (obj->obj.import_attach) { 287 - ret = -EINVAL; 288 - goto err_unref; 289 - } 290 - 291 - ret = drm_gem_create_mmap_offset(&obj->obj); 292 - if (ret == 0) { 293 - *offset = drm_vma_node_offset_addr(&obj->obj.vma_node); 294 - DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset); 295 - } 296 - 297 - err_unref: 298 - drm_gem_object_unreference_unlocked(&obj->obj); 299 - 300 - return ret; 301 - } 302 - 303 - int armada_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, 304 - uint32_t handle) 305 - { 306 - return drm_gem_handle_delete(file, handle); 307 - } 308 - 309 273 /* Private driver gem ioctls */ 310 274 int armada_gem_create_ioctl(struct drm_device *dev, void *data, 311 275 struct drm_file *file)
-4
drivers/gpu/drm/armada/armada_gem.h
··· 35 35 size_t); 36 36 int armada_gem_dumb_create(struct drm_file *, struct drm_device *, 37 37 struct drm_mode_create_dumb *); 38 - int armada_gem_dumb_map_offset(struct drm_file *, struct drm_device *, 39 - uint32_t, uint64_t *); 40 - int armada_gem_dumb_destroy(struct drm_file *, struct drm_device *, 41 - uint32_t); 42 38 struct dma_buf *armada_gem_prime_export(struct drm_device *dev, 43 39 struct drm_gem_object *obj, int flags); 44 40 struct drm_gem_object *armada_gem_prime_import(struct drm_device *,
+1 -1
drivers/gpu/drm/armada/armada_trace.h
··· 62 62 63 63 /* This part must be outside protection */ 64 64 #undef TRACE_INCLUDE_PATH 65 - #define TRACE_INCLUDE_PATH . 65 + #define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/armada 66 66 #include <trace/define_trace.h>
+1 -1
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
··· 458 458 static struct drm_framebuffer *atmel_hlcdc_fb_create(struct drm_device *dev, 459 459 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) 460 460 { 461 - return drm_fb_cma_create(dev, file_priv, mode_cmd); 461 + return drm_gem_fb_create(dev, file_priv, mode_cmd); 462 462 } 463 463 464 464 static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
+1
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
··· 34 34 #include <drm/drm_crtc_helper.h> 35 35 #include <drm/drm_fb_cma_helper.h> 36 36 #include <drm/drm_gem_cma_helper.h> 37 + #include <drm/drm_gem_framebuffer_helper.h> 37 38 #include <drm/drm_panel.h> 38 39 #include <drm/drm_plane_helper.h> 39 40 #include <drm/drmP.h>
-2
drivers/gpu/drm/bridge/adv7511/adv7511.h
··· 328 328 enum adv7511_sync_polarity hsync_polarity; 329 329 bool rgb; 330 330 331 - struct edid *edid; 332 - 333 331 struct gpio_desc *gpio_pd; 334 332 335 333 struct regulator_bulk_data *supplies;
+1 -1
drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
··· 210 210 .get_dai_id = adv7511_hdmi_i2s_get_dai_id, 211 211 }; 212 212 213 - static struct hdmi_codec_pdata codec_data = { 213 + static const struct hdmi_codec_pdata codec_data = { 214 214 .ops = &adv7511_codec_ops, 215 215 .max_i2s_channels = 2, 216 216 .i2s = 1,
+11 -13
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
··· 199 199 200 200 static void adv7511_set_config_csc(struct adv7511 *adv7511, 201 201 struct drm_connector *connector, 202 - bool rgb) 202 + bool rgb, bool hdmi_mode) 203 203 { 204 204 struct adv7511_video_config config; 205 205 bool output_format_422, output_format_ycbcr; 206 206 unsigned int mode; 207 207 uint8_t infoframe[17]; 208 208 209 - if (adv7511->edid) 210 - config.hdmi_mode = drm_detect_hdmi_monitor(adv7511->edid); 211 - else 212 - config.hdmi_mode = false; 209 + config.hdmi_mode = hdmi_mode; 213 210 214 211 hdmi_avi_infoframe_init(&config.avi_infoframe); 215 212 ··· 586 589 if (!adv7511->powered) 587 590 __adv7511_power_off(adv7511); 588 591 589 - kfree(adv7511->edid); 590 - adv7511->edid = edid; 591 - if (!edid) 592 - return 0; 593 592 594 593 drm_mode_connector_update_edid_property(connector, edid); 595 594 count = drm_add_edid_modes(connector, edid); 596 595 597 - adv7511_set_config_csc(adv7511, connector, adv7511->rgb); 596 + adv7511_set_config_csc(adv7511, connector, adv7511->rgb, 597 + drm_detect_hdmi_monitor(edid)); 598 + 599 + kfree(edid); 598 600 599 601 return count; 600 602 } ··· 829 833 return -ENODEV; 830 834 } 831 835 832 - adv->connector.polled = DRM_CONNECTOR_POLL_HPD; 836 + if (adv->i2c_main->irq) 837 + adv->connector.polled = DRM_CONNECTOR_POLL_HPD; 838 + else 839 + adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT | 840 + DRM_CONNECTOR_POLL_DISCONNECT; 833 841 834 842 ret = drm_connector_init(bridge->dev, &adv->connector, 835 843 &adv7511_connector_funcs, ··· 1157 1157 adv7511_audio_exit(adv7511); 1158 1158 1159 1159 i2c_unregister_device(adv7511->i2c_edid); 1160 - 1161 - kfree(adv7511->edid); 1162 1160 1163 1161 return 0; 1164 1162 }
+61 -42
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
··· 30 30 #include <video/mipi_display.h> 31 31 32 32 #define DSI_VERSION 0x00 33 + 33 34 #define DSI_PWR_UP 0x04 34 35 #define RESET 0 35 36 #define POWERUP BIT(0) 36 37 37 38 #define DSI_CLKMGR_CFG 0x08 38 - #define TO_CLK_DIVIDSION(div) (((div) & 0xff) << 8) 39 - #define TX_ESC_CLK_DIVIDSION(div) (((div) & 0xff) << 0) 39 + #define TO_CLK_DIVISION(div) (((div) & 0xff) << 8) 40 + #define TX_ESC_CLK_DIVISION(div) ((div) & 0xff) 40 41 41 42 #define DSI_DPI_VCID 0x0c 42 - #define DPI_VID(vid) (((vid) & 0x3) << 0) 43 + #define DPI_VCID(vcid) ((vcid) & 0x3) 43 44 44 45 #define DSI_DPI_COLOR_CODING 0x10 45 - #define EN18_LOOSELY BIT(8) 46 + #define LOOSELY18_EN BIT(8) 46 47 #define DPI_COLOR_CODING_16BIT_1 0x0 47 48 #define DPI_COLOR_CODING_16BIT_2 0x1 48 49 #define DPI_COLOR_CODING_16BIT_3 0x2 ··· 62 61 #define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16) 63 62 #define INVACT_LPCMD_TIME(p) ((p) & 0xff) 64 63 64 + #define DSI_DBI_VCID 0x1c 65 65 #define DSI_DBI_CFG 0x20 66 + #define DSI_DBI_PARTITIONING_EN 0x24 66 67 #define DSI_DBI_CMDSIZE 0x28 67 68 68 69 #define DSI_PCKHDL_CFG 0x2c 69 - #define EN_CRC_RX BIT(4) 70 - #define EN_ECC_RX BIT(3) 71 - #define EN_BTA BIT(2) 72 - #define EN_EOTP_RX BIT(1) 73 - #define EN_EOTP_TX BIT(0) 70 + #define CRC_RX_EN BIT(4) 71 + #define ECC_RX_EN BIT(3) 72 + #define BTA_EN BIT(2) 73 + #define EOTP_RX_EN BIT(1) 74 + #define EOTP_TX_EN BIT(0) 75 + 76 + #define DSI_GEN_VCID 0x30 74 77 75 78 #define DSI_MODE_CFG 0x34 76 79 #define ENABLE_VIDEO_MODE 0 77 80 #define ENABLE_CMD_MODE BIT(0) 78 81 79 82 #define DSI_VID_MODE_CFG 0x38 80 - #define FRAME_BTA_ACK BIT(14) 81 83 #define ENABLE_LOW_POWER (0x3f << 8) 82 84 #define ENABLE_LOW_POWER_MASK (0x3f << 8) 83 85 #define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0 ··· 89 85 #define VID_MODE_TYPE_MASK 0x3 90 86 91 87 #define DSI_VID_PKT_SIZE 0x3c 92 - #define VID_PKT_SIZE(p) (((p) & 0x3fff) << 0) 93 - #define VID_PKT_MAX_SIZE 0x3fff 88 + #define VID_PKT_SIZE(p) ((p) & 0x3fff) 89 + 90 + #define DSI_VID_NUM_CHUNKS 0x40 91 + #define VID_NUM_CHUNKS(c) ((c) & 0x1fff) 92 + 93 + #define DSI_VID_NULL_SIZE 0x44 94 + #define VID_NULL_SIZE(b) ((b) & 0x1fff) 94 95 95 96 #define DSI_VID_HSA_TIME 0x48 96 97 #define DSI_VID_HBP_TIME 0x4c ··· 104 95 #define DSI_VID_VBP_LINES 0x58 105 96 #define DSI_VID_VFP_LINES 0x5c 106 97 #define DSI_VID_VACTIVE_LINES 0x60 98 + #define DSI_EDPI_CMD_SIZE 0x64 99 + 107 100 #define DSI_CMD_MODE_CFG 0x68 108 101 #define MAX_RD_PKT_SIZE_LP BIT(24) 109 102 #define DCS_LW_TX_LP BIT(19) ··· 119 108 #define GEN_SW_2P_TX_LP BIT(10) 120 109 #define GEN_SW_1P_TX_LP BIT(9) 121 110 #define GEN_SW_0P_TX_LP BIT(8) 122 - #define EN_ACK_RQST BIT(1) 123 - #define EN_TEAR_FX BIT(0) 111 + #define ACK_RQST_EN BIT(1) 112 + #define TEAR_FX_EN BIT(0) 124 113 125 114 #define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \ 126 115 DCS_LW_TX_LP | \ ··· 136 125 GEN_SW_0P_TX_LP) 137 126 138 127 #define DSI_GEN_HDR 0x6c 128 + /* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */ 139 129 #define GEN_HDATA(data) (((data) & 0xffff) << 8) 140 - #define GEN_HDATA_MASK (0xffff << 8) 141 130 #define GEN_HTYPE(type) (((type) & 0xff) << 0) 142 - #define GEN_HTYPE_MASK 0xff 143 131 144 132 #define DSI_GEN_PLD_DATA 0x70 145 133 146 134 #define DSI_CMD_PKT_STATUS 0x74 147 - #define GEN_CMD_EMPTY BIT(0) 148 - #define GEN_CMD_FULL BIT(1) 149 - #define GEN_PLD_W_EMPTY BIT(2) 150 - #define GEN_PLD_W_FULL BIT(3) 151 - #define GEN_PLD_R_EMPTY BIT(4) 152 - #define GEN_PLD_R_FULL BIT(5) 153 135 #define GEN_RD_CMD_BUSY BIT(6) 136 + #define GEN_PLD_R_FULL BIT(5) 137 + #define GEN_PLD_R_EMPTY BIT(4) 138 + #define GEN_PLD_W_FULL BIT(3) 139 + #define GEN_PLD_W_EMPTY BIT(2) 140 + #define GEN_CMD_FULL BIT(1) 141 + #define GEN_CMD_EMPTY BIT(0) 154 142 155 143 #define DSI_TO_CNT_CFG 0x78 156 144 #define HSTX_TO_CNT(p) (((p) & 0xffff) << 16) 157 145 #define LPRX_TO_CNT(p) ((p) & 0xffff) 158 146 147 + #define DSI_HS_RD_TO_CNT 0x7c 148 + #define DSI_LP_RD_TO_CNT 0x80 149 + #define DSI_HS_WR_TO_CNT 0x84 150 + #define DSI_LP_WR_TO_CNT 0x88 159 151 #define DSI_BTA_TO_CNT 0x8c 152 + 160 153 #define DSI_LPCLK_CTRL 0x94 161 154 #define AUTO_CLKLANE_CTRL BIT(1) 162 155 #define PHY_TXREQUESTCLKHS BIT(0) ··· 169 154 #define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16) 170 155 #define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff) 171 156 157 + /* TODO Next register is slightly different between 1.30 & 1.31 IP version */ 172 158 #define DSI_PHY_TMR_CFG 0x9c 173 159 #define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24) 174 160 #define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16) ··· 186 170 #define PHY_UNSHUTDOWNZ BIT(0) 187 171 188 172 #define DSI_PHY_IF_CFG 0xa4 189 - #define N_LANES(n) ((((n) - 1) & 0x3) << 0) 190 173 #define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8) 174 + #define N_LANES(n) (((n) - 1) & 0x3) 175 + 176 + #define DSI_PHY_ULPS_CTRL 0xa8 177 + #define DSI_PHY_TX_TRIGGERS 0xac 191 178 192 179 #define DSI_PHY_STATUS 0xb0 193 - #define LOCK BIT(0) 194 - #define STOP_STATE_CLK_LANE BIT(2) 180 + #define PHY_STOP_STATE_CLK_LANE BIT(2) 181 + #define PHY_LOCK BIT(0) 195 182 196 183 #define DSI_PHY_TST_CTRL0 0xb4 197 184 #define PHY_TESTCLK BIT(1) ··· 206 187 #define PHY_TESTEN BIT(16) 207 188 #define PHY_UNTESTEN 0 208 189 #define PHY_TESTDOUT(n) (((n) & 0xff) << 8) 209 - #define PHY_TESTDIN(n) (((n) & 0xff) << 0) 190 + #define PHY_TESTDIN(n) ((n) & 0xff) 210 191 211 192 #define DSI_INT_ST0 0xbc 212 193 #define DSI_INT_ST1 0xc0 213 194 #define DSI_INT_MSK0 0xc4 214 195 #define DSI_INT_MSK1 0xc8 196 + #define DSI_PHY_TMR_RD_CFG 0xf4 215 197 216 198 #define PHY_STATUS_TIMEOUT_US 10000 217 199 #define CMD_PKT_STATUS_TIMEOUT_US 20000 ··· 327 307 u32 val = 0; 328 308 329 309 if (msg->flags & MIPI_DSI_MSG_REQ_ACK) 330 - val |= EN_ACK_RQST; 310 + val |= ACK_RQST_EN; 331 311 if (lpm) 332 312 val |= CMD_MODE_ALL_LP; 333 313 ··· 526 506 * timeout clock division should be computed with the 527 507 * high speed transmission counter timeout and byte lane... 528 508 */ 529 - dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) | 530 - TX_ESC_CLK_DIVIDSION(esc_clk_division)); 509 + dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | 510 + TX_ESC_CLK_DIVISION(esc_clk_division)); 531 511 } 532 512 533 513 static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, ··· 540 520 color = DPI_COLOR_CODING_24BIT; 541 521 break; 542 522 case MIPI_DSI_FMT_RGB666: 543 - color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY; 523 + color = DPI_COLOR_CODING_18BIT_2 | LOOSELY18_EN; 544 524 break; 545 525 case MIPI_DSI_FMT_RGB666_PACKED: 546 526 color = DPI_COLOR_CODING_18BIT_1; ··· 555 535 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 556 536 val |= HSYNC_ACTIVE_LOW; 557 537 558 - dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel)); 538 + dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); 559 539 dsi_write(dsi, DSI_DPI_COLOR_CODING, color); 560 540 dsi_write(dsi, DSI_DPI_CFG_POL, val); 561 541 /* ··· 570 550 571 551 static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) 572 552 { 573 - dsi_write(dsi, DSI_PCKHDL_CFG, EN_CRC_RX | EN_ECC_RX | EN_BTA); 553 + dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN); 574 554 } 575 555 576 556 static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, ··· 591 571 /* 592 572 * TODO dw drv improvements 593 573 * compute high speed transmission counter timeout according 594 - * to the timeout clock division (TO_CLK_DIVIDSION) and byte lane... 574 + * to the timeout clock division (TO_CLK_DIVISION) and byte lane... 595 575 */ 596 576 dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); 597 577 /* ··· 704 684 dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK | 705 685 PHY_UNRSTZ | PHY_UNSHUTDOWNZ); 706 686 707 - ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 708 - val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US); 687 + ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val, 688 + val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US); 709 689 if (ret < 0) 710 690 DRM_DEBUG_DRIVER("failed to wait phy lock state\n"); 711 691 712 692 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 713 - val, val & STOP_STATE_CLK_LANE, 1000, 693 + val, val & PHY_STOP_STATE_CLK_LANE, 1000, 714 694 PHY_STATUS_TIMEOUT_US); 715 695 if (ret < 0) 716 696 DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n"); ··· 885 865 * Note that the reset was not defined in the initial device tree, so 886 866 * we have to be prepared for it not being found. 887 867 */ 888 - apb_rst = devm_reset_control_get(dev, "apb"); 868 + apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb"); 889 869 if (IS_ERR(apb_rst)) { 890 870 ret = PTR_ERR(apb_rst); 891 - if (ret == -ENOENT) { 892 - apb_rst = NULL; 893 - } else { 871 + 872 + if (ret != -EPROBE_DEFER) 894 873 dev_err(dev, "Unable to get reset control: %d\n", ret); 895 - return ERR_PTR(ret); 896 - } 874 + 875 + return ERR_PTR(ret); 897 876 } 898 877 899 878 if (apb_rst) {
+8 -10
drivers/gpu/drm/drm_atomic.c
··· 163 163 crtc->funcs->atomic_destroy_state(crtc, 164 164 state->crtcs[i].state); 165 165 166 - if (state->crtcs[i].commit) { 167 - kfree(state->crtcs[i].commit->event); 168 - state->crtcs[i].commit->event = NULL; 169 - drm_crtc_commit_put(state->crtcs[i].commit); 170 - } 171 - 172 - state->crtcs[i].commit = NULL; 173 166 state->crtcs[i].ptr = NULL; 174 167 state->crtcs[i].state = NULL; 175 168 } ··· 192 199 } 193 200 state->num_private_objs = 0; 194 201 202 + if (state->fake_commit) { 203 + drm_crtc_commit_put(state->fake_commit); 204 + state->fake_commit = NULL; 205 + } 195 206 } 196 207 EXPORT_SYMBOL(drm_atomic_state_default_clear); 197 208 ··· 2234 2237 (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) 2235 2238 return -EINVAL; 2236 2239 2237 - drm_modeset_acquire_init(&ctx, 0); 2240 + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 2238 2241 2239 2242 state = drm_atomic_state_alloc(dev); 2240 2243 if (!state) ··· 2347 2350 2348 2351 if (ret == -EDEADLK) { 2349 2352 drm_atomic_state_clear(state); 2350 - drm_modeset_backoff(&ctx); 2351 - goto retry; 2353 + ret = drm_modeset_backoff(&ctx); 2354 + if (!ret) 2355 + goto retry; 2352 2356 } 2353 2357 2354 2358 drm_atomic_state_put(state);
+212 -105
drivers/gpu/drm/drm_atomic_helper.c
··· 1262 1262 void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, 1263 1263 struct drm_atomic_state *old_state) 1264 1264 { 1265 - struct drm_crtc_state *unused; 1265 + struct drm_crtc_state *new_crtc_state; 1266 1266 struct drm_crtc *crtc; 1267 1267 int i; 1268 1268 1269 - for_each_new_crtc_in_state(old_state, crtc, unused, i) { 1270 - struct drm_crtc_commit *commit = old_state->crtcs[i].commit; 1269 + for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1270 + struct drm_crtc_commit *commit = new_crtc_state->commit; 1271 1271 int ret; 1272 1272 1273 1273 if (!commit) ··· 1388 1388 { 1389 1389 struct drm_crtc *crtc; 1390 1390 struct drm_crtc_state *crtc_state; 1391 - struct drm_crtc_commit *commit; 1392 - struct drm_plane *__plane, *plane = NULL; 1393 - struct drm_plane_state *__plane_state, *plane_state = NULL; 1391 + struct drm_plane *plane; 1392 + struct drm_plane_state *old_plane_state, *new_plane_state; 1394 1393 const struct drm_plane_helper_funcs *funcs; 1395 - int i, j, n_planes = 0; 1394 + int i, n_planes = 0; 1396 1395 1397 1396 for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 1398 1397 if (drm_atomic_crtc_needs_modeset(crtc_state)) 1399 1398 return -EINVAL; 1400 1399 } 1401 1400 1402 - for_each_new_plane_in_state(state, __plane, __plane_state, i) { 1401 + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) 1403 1402 n_planes++; 1404 - plane = __plane; 1405 - plane_state = __plane_state; 1406 - } 1407 1403 1408 1404 /* FIXME: we support only single plane updates for now */ 1409 - if (!plane || n_planes != 1) 1405 + if (n_planes != 1) 1410 1406 return -EINVAL; 1411 1407 1412 - if (!plane_state->crtc) 1408 + if (!new_plane_state->crtc) 1413 1409 return -EINVAL; 1414 1410 1415 1411 funcs = plane->helper_private; 1416 1412 if (!funcs->atomic_async_update) 1417 1413 return -EINVAL; 1418 1414 1419 - if (plane_state->fence) 1415 + if (new_plane_state->fence) 1420 1416 return -EINVAL; 1421 1417 1422 1418 /* ··· 1420 1424 * the plane. This prevents our async update's changes from getting 1421 1425 * overridden by a previous synchronous update's state. 1422 1426 */ 1423 - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 1424 - if (plane->crtc != crtc) 1425 - continue; 1427 + if (old_plane_state->commit && 1428 + !try_wait_for_completion(&old_plane_state->commit->hw_done)) 1429 + return -EBUSY; 1426 1430 1427 - spin_lock(&crtc->commit_lock); 1428 - commit = list_first_entry_or_null(&crtc->commit_list, 1429 - struct drm_crtc_commit, 1430 - commit_entry); 1431 - if (!commit) { 1432 - spin_unlock(&crtc->commit_lock); 1433 - continue; 1434 - } 1435 - spin_unlock(&crtc->commit_lock); 1436 - 1437 - if (!crtc->state->state) 1438 - continue; 1439 - 1440 - for_each_plane_in_state(crtc->state->state, __plane, 1441 - __plane_state, j) { 1442 - if (__plane == plane) 1443 - return -EINVAL; 1444 - } 1445 - } 1446 - 1447 - return funcs->atomic_async_check(plane, plane_state); 1431 + return funcs->atomic_async_check(plane, new_plane_state); 1448 1432 } 1449 1433 EXPORT_SYMBOL(drm_atomic_helper_async_check); 1450 1434 ··· 1609 1633 return -EBUSY; 1610 1634 } 1611 1635 } else if (i == 1) { 1612 - stall_commit = commit; 1613 - drm_crtc_commit_get(stall_commit); 1636 + stall_commit = drm_crtc_commit_get(commit); 1614 1637 break; 1615 1638 } 1616 1639 ··· 1641 1666 flip_done); 1642 1667 1643 1668 drm_crtc_commit_put(commit); 1669 + } 1670 + 1671 + static void init_commit(struct drm_crtc_commit *commit, struct drm_crtc *crtc) 1672 + { 1673 + init_completion(&commit->flip_done); 1674 + init_completion(&commit->hw_done); 1675 + init_completion(&commit->cleanup_done); 1676 + INIT_LIST_HEAD(&commit->commit_entry); 1677 + kref_init(&commit->ref); 1678 + commit->crtc = crtc; 1679 + } 1680 + 1681 + static struct drm_crtc_commit * 1682 + crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc) 1683 + { 1684 + if (crtc) { 1685 + struct drm_crtc_state *new_crtc_state; 1686 + 1687 + new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1688 + 1689 + return new_crtc_state->commit; 1690 + } 1691 + 1692 + if (!state->fake_commit) { 1693 + state->fake_commit = kzalloc(sizeof(*state->fake_commit), GFP_KERNEL); 1694 + if (!state->fake_commit) 1695 + return NULL; 1696 + 1697 + init_commit(state->fake_commit, NULL); 1698 + } 1699 + 1700 + return state->fake_commit; 1644 1701 } 1645 1702 1646 1703 /** ··· 1723 1716 { 1724 1717 struct drm_crtc *crtc; 1725 1718 struct drm_crtc_state *old_crtc_state, *new_crtc_state; 1719 + struct drm_connector *conn; 1720 + struct drm_connector_state *old_conn_state, *new_conn_state; 1721 + struct drm_plane *plane; 1722 + struct drm_plane_state *old_plane_state, *new_plane_state; 1726 1723 struct drm_crtc_commit *commit; 1727 1724 int i, ret; 1728 1725 ··· 1735 1724 if (!commit) 1736 1725 return -ENOMEM; 1737 1726 1738 - init_completion(&commit->flip_done); 1739 - init_completion(&commit->hw_done); 1740 - init_completion(&commit->cleanup_done); 1741 - INIT_LIST_HEAD(&commit->commit_entry); 1742 - kref_init(&commit->ref); 1743 - commit->crtc = crtc; 1727 + init_commit(commit, crtc); 1744 1728 1745 - state->crtcs[i].commit = commit; 1729 + new_crtc_state->commit = commit; 1746 1730 1747 1731 ret = stall_checks(crtc, nonblock); 1748 1732 if (ret) ··· 1771 1765 drm_crtc_commit_get(commit); 1772 1766 } 1773 1767 1768 + for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) { 1769 + /* commit tracked through new_crtc_state->commit, no need to do it explicitly */ 1770 + if (new_conn_state->crtc) 1771 + continue; 1772 + 1773 + /* Userspace is not allowed to get ahead of the previous 1774 + * commit with nonblocking ones. */ 1775 + if (nonblock && old_conn_state->commit && 1776 + !try_wait_for_completion(&old_conn_state->commit->flip_done)) 1777 + return -EBUSY; 1778 + 1779 + commit = crtc_or_fake_commit(state, old_conn_state->crtc); 1780 + if (!commit) 1781 + return -ENOMEM; 1782 + 1783 + new_conn_state->commit = drm_crtc_commit_get(commit); 1784 + } 1785 + 1786 + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { 1787 + /* 1788 + * Unlike connectors, always track planes explicitly for 1789 + * async pageflip support. 1790 + */ 1791 + 1792 + /* Userspace is not allowed to get ahead of the previous 1793 + * commit with nonblocking ones. */ 1794 + if (nonblock && old_plane_state->commit && 1795 + !try_wait_for_completion(&old_plane_state->commit->flip_done)) 1796 + return -EBUSY; 1797 + 1798 + commit = crtc_or_fake_commit(state, old_plane_state->crtc); 1799 + if (!commit) 1800 + return -ENOMEM; 1801 + 1802 + new_plane_state->commit = drm_crtc_commit_get(commit); 1803 + } 1804 + 1774 1805 return 0; 1775 1806 } 1776 1807 EXPORT_SYMBOL(drm_atomic_helper_setup_commit); 1777 - 1778 - 1779 - static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc) 1780 - { 1781 - struct drm_crtc_commit *commit; 1782 - int i = 0; 1783 - 1784 - list_for_each_entry(commit, &crtc->commit_list, commit_entry) { 1785 - /* skip the first entry, that's the current commit */ 1786 - if (i == 1) 1787 - return commit; 1788 - i++; 1789 - } 1790 - 1791 - return NULL; 1792 - } 1793 1808 1794 1809 /** 1795 1810 * drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits ··· 1827 1800 void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state) 1828 1801 { 1829 1802 struct drm_crtc *crtc; 1830 - struct drm_crtc_state *new_crtc_state; 1803 + struct drm_crtc_state *old_crtc_state; 1804 + struct drm_plane *plane; 1805 + struct drm_plane_state *old_plane_state; 1806 + struct drm_connector *conn; 1807 + struct drm_connector_state *old_conn_state; 1831 1808 struct drm_crtc_commit *commit; 1832 1809 int i; 1833 1810 long ret; 1834 1811 1835 - for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1836 - spin_lock(&crtc->commit_lock); 1837 - commit = preceeding_commit(crtc); 1838 - if (commit) 1839 - drm_crtc_commit_get(commit); 1840 - spin_unlock(&crtc->commit_lock); 1812 + for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { 1813 + commit = old_crtc_state->commit; 1841 1814 1842 1815 if (!commit) 1843 1816 continue; ··· 1855 1828 if (ret == 0) 1856 1829 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", 1857 1830 crtc->base.id, crtc->name); 1831 + } 1858 1832 1859 - drm_crtc_commit_put(commit); 1833 + for_each_old_connector_in_state(old_state, conn, old_conn_state, i) { 1834 + commit = old_conn_state->commit; 1835 + 1836 + if (!commit) 1837 + continue; 1838 + 1839 + ret = wait_for_completion_timeout(&commit->hw_done, 1840 + 10*HZ); 1841 + if (ret == 0) 1842 + DRM_ERROR("[CONNECTOR:%d:%s] hw_done timed out\n", 1843 + conn->base.id, conn->name); 1844 + 1845 + /* Currently no support for overwriting flips, hence 1846 + * stall for previous one to execute completely. */ 1847 + ret = wait_for_completion_timeout(&commit->flip_done, 1848 + 10*HZ); 1849 + if (ret == 0) 1850 + DRM_ERROR("[CONNECTOR:%d:%s] flip_done timed out\n", 1851 + conn->base.id, conn->name); 1852 + } 1853 + 1854 + for_each_old_plane_in_state(old_state, plane, old_plane_state, i) { 1855 + commit = old_plane_state->commit; 1856 + 1857 + if (!commit) 1858 + continue; 1859 + 1860 + ret = wait_for_completion_timeout(&commit->hw_done, 1861 + 10*HZ); 1862 + if (ret == 0) 1863 + DRM_ERROR("[PLANE:%d:%s] hw_done timed out\n", 1864 + plane->base.id, plane->name); 1865 + 1866 + /* Currently no support for overwriting flips, hence 1867 + * stall for previous one to execute completely. */ 1868 + ret = wait_for_completion_timeout(&commit->flip_done, 1869 + 10*HZ); 1870 + if (ret == 0) 1871 + DRM_ERROR("[PLANE:%d:%s] flip_done timed out\n", 1872 + plane->base.id, plane->name); 1860 1873 } 1861 1874 } 1862 1875 EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); ··· 1919 1852 void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state) 1920 1853 { 1921 1854 struct drm_crtc *crtc; 1922 - struct drm_crtc_state *new_crtc_state; 1855 + struct drm_crtc_state *old_crtc_state, *new_crtc_state; 1923 1856 struct drm_crtc_commit *commit; 1924 1857 int i; 1925 1858 1926 - for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1927 - commit = old_state->crtcs[i].commit; 1859 + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { 1860 + commit = new_crtc_state->commit; 1928 1861 if (!commit) 1929 1862 continue; 1863 + 1864 + /* 1865 + * copy new_crtc_state->commit to old_crtc_state->commit, 1866 + * it's unsafe to touch new_crtc_state after hw_done, 1867 + * but we still need to do so in cleanup_done(). 1868 + */ 1869 + if (old_crtc_state->commit) 1870 + drm_crtc_commit_put(old_crtc_state->commit); 1871 + 1872 + old_crtc_state->commit = drm_crtc_commit_get(commit); 1930 1873 1931 1874 /* backend must have consumed any event by now */ 1932 1875 WARN_ON(new_crtc_state->event); 1933 1876 complete_all(&commit->hw_done); 1877 + } 1878 + 1879 + if (old_state->fake_commit) { 1880 + complete_all(&old_state->fake_commit->hw_done); 1881 + complete_all(&old_state->fake_commit->flip_done); 1934 1882 } 1935 1883 } 1936 1884 EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done); ··· 1964 1882 void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state) 1965 1883 { 1966 1884 struct drm_crtc *crtc; 1967 - struct drm_crtc_state *new_crtc_state; 1885 + struct drm_crtc_state *old_crtc_state; 1968 1886 struct drm_crtc_commit *commit; 1969 1887 int i; 1970 - long ret; 1971 1888 1972 - for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1973 - commit = old_state->crtcs[i].commit; 1889 + for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { 1890 + commit = old_crtc_state->commit; 1974 1891 if (WARN_ON(!commit)) 1975 1892 continue; 1976 1893 1977 1894 complete_all(&commit->cleanup_done); 1978 1895 WARN_ON(!try_wait_for_completion(&commit->hw_done)); 1979 1896 1980 - /* commit_list borrows our reference, need to remove before we 1981 - * clean up our drm_atomic_state. But only after it actually 1982 - * completed, otherwise subsequent commits won't stall properly. */ 1983 - if (try_wait_for_completion(&commit->flip_done)) 1984 - goto del_commit; 1985 - 1986 - /* We must wait for the vblank event to signal our completion 1987 - * before releasing our reference, since the vblank work does 1988 - * not hold a reference of its own. */ 1989 - ret = wait_for_completion_timeout(&commit->flip_done, 1990 - 10*HZ); 1991 - if (ret == 0) 1992 - DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", 1993 - crtc->base.id, crtc->name); 1994 - 1995 - del_commit: 1996 1897 spin_lock(&crtc->commit_lock); 1997 1898 list_del(&commit->commit_entry); 1998 1899 spin_unlock(&crtc->commit_lock); 1999 1900 } 1901 + 1902 + if (old_state->fake_commit) 1903 + complete_all(&old_state->fake_commit->cleanup_done); 2000 1904 } 2001 1905 EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done); 2002 1906 ··· 2362 2294 struct drm_private_state *old_obj_state, *new_obj_state; 2363 2295 2364 2296 if (stall) { 2365 - for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 2366 - spin_lock(&crtc->commit_lock); 2367 - commit = list_first_entry_or_null(&crtc->commit_list, 2368 - struct drm_crtc_commit, commit_entry); 2369 - if (commit) 2370 - drm_crtc_commit_get(commit); 2371 - spin_unlock(&crtc->commit_lock); 2297 + /* 2298 + * We have to stall for hw_done here before 2299 + * drm_atomic_helper_wait_for_dependencies() because flip 2300 + * depth > 1 is not yet supported by all drivers. As long as 2301 + * obj->state is directly dereferenced anywhere in the drivers 2302 + * atomic_commit_tail function, then it's unsafe to swap state 2303 + * before drm_atomic_helper_commit_hw_done() is called. 2304 + */ 2305 + 2306 + for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { 2307 + commit = old_crtc_state->commit; 2372 2308 2373 2309 if (!commit) 2374 2310 continue; 2375 2311 2376 2312 ret = wait_for_completion_interruptible(&commit->hw_done); 2377 - drm_crtc_commit_put(commit); 2313 + if (ret) 2314 + return ret; 2315 + } 2378 2316 2317 + for_each_old_connector_in_state(state, connector, old_conn_state, i) { 2318 + commit = old_conn_state->commit; 2319 + 2320 + if (!commit) 2321 + continue; 2322 + 2323 + ret = wait_for_completion_interruptible(&commit->hw_done); 2324 + if (ret) 2325 + return ret; 2326 + } 2327 + 2328 + for_each_old_plane_in_state(state, plane, old_plane_state, i) { 2329 + commit = old_plane_state->commit; 2330 + 2331 + if (!commit) 2332 + continue; 2333 + 2334 + ret = wait_for_completion_interruptible(&commit->hw_done); 2379 2335 if (ret) 2380 2336 return ret; 2381 2337 } ··· 2424 2332 state->crtcs[i].state = old_crtc_state; 2425 2333 crtc->state = new_crtc_state; 2426 2334 2427 - if (state->crtcs[i].commit) { 2335 + if (new_crtc_state->commit) { 2428 2336 spin_lock(&crtc->commit_lock); 2429 - list_add(&state->crtcs[i].commit->commit_entry, 2337 + list_add(&new_crtc_state->commit->commit_entry, 2430 2338 &crtc->commit_list); 2431 2339 spin_unlock(&crtc->commit_lock); 2432 2340 2433 - state->crtcs[i].commit->event = NULL; 2341 + new_crtc_state->commit->event = NULL; 2434 2342 } 2435 2343 } 2436 2344 ··· 3278 3186 state->connectors_changed = false; 3279 3187 state->color_mgmt_changed = false; 3280 3188 state->zpos_changed = false; 3189 + state->commit = NULL; 3281 3190 state->event = NULL; 3282 3191 state->pageflip_flags = 0; 3283 3192 } ··· 3317 3224 */ 3318 3225 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) 3319 3226 { 3227 + if (state->commit) { 3228 + kfree(state->commit->event); 3229 + state->commit->event = NULL; 3230 + drm_crtc_commit_put(state->commit); 3231 + } 3232 + 3320 3233 drm_property_blob_put(state->mode_blob); 3321 3234 drm_property_blob_put(state->degamma_lut); 3322 3235 drm_property_blob_put(state->ctm); ··· 3385 3286 drm_framebuffer_get(state->fb); 3386 3287 3387 3288 state->fence = NULL; 3289 + state->commit = NULL; 3388 3290 } 3389 3291 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); 3390 3292 ··· 3427 3327 3428 3328 if (state->fence) 3429 3329 dma_fence_put(state->fence); 3330 + 3331 + if (state->commit) 3332 + drm_crtc_commit_put(state->commit); 3430 3333 } 3431 3334 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); 3432 3335 ··· 3508 3405 memcpy(state, connector->state, sizeof(*state)); 3509 3406 if (state->crtc) 3510 3407 drm_connector_get(connector); 3408 + state->commit = NULL; 3511 3409 } 3512 3410 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); 3513 3411 ··· 3635 3531 { 3636 3532 if (state->crtc) 3637 3533 drm_connector_put(state->connector); 3534 + 3535 + if (state->commit) 3536 + drm_crtc_commit_put(state->commit); 3638 3537 } 3639 3538 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); 3640 3539
+1 -6
drivers/gpu/drm/drm_bridge.c
··· 67 67 * drm_bridge_add - add the given bridge to the global bridge list 68 68 * 69 69 * @bridge: bridge control structure 70 - * 71 - * RETURNS: 72 - * Unconditionally returns Zero. 73 70 */ 74 - int drm_bridge_add(struct drm_bridge *bridge) 71 + void drm_bridge_add(struct drm_bridge *bridge) 75 72 { 76 73 mutex_lock(&bridge_lock); 77 74 list_add_tail(&bridge->list, &bridge_list); 78 75 mutex_unlock(&bridge_lock); 79 - 80 - return 0; 81 76 } 82 77 EXPORT_SYMBOL(drm_bridge_add); 83 78
-1
drivers/gpu/drm/drm_connector.c
··· 615 615 { DRM_MODE_LINK_STATUS_GOOD, "Good" }, 616 616 { DRM_MODE_LINK_STATUS_BAD, "Bad" }, 617 617 }; 618 - DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list) 619 618 620 619 /** 621 620 * drm_display_info_set_bus_formats - set the supported bus formats
+4 -3
drivers/gpu/drm/drm_crtc.c
··· 577 577 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); 578 578 579 579 mutex_lock(&crtc->dev->mode_config.mutex); 580 - drm_modeset_acquire_init(&ctx, 0); 580 + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 581 581 retry: 582 582 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); 583 583 if (ret) ··· 717 717 kfree(connector_set); 718 718 drm_mode_destroy(dev, mode); 719 719 if (ret == -EDEADLK) { 720 - drm_modeset_backoff(&ctx); 721 - goto retry; 720 + ret = drm_modeset_backoff(&ctx); 721 + if (!ret) 722 + goto retry; 722 723 } 723 724 drm_modeset_drop_locks(&ctx); 724 725 drm_modeset_acquire_fini(&ctx);
+1 -1
drivers/gpu/drm/drm_debugfs_crc.c
··· 155 155 int ret = 0; 156 156 157 157 if (drm_drv_uses_atomic_modeset(crtc->dev)) { 158 - ret = drm_modeset_lock_interruptible(&crtc->mutex, NULL); 158 + ret = drm_modeset_lock_single_interruptible(&crtc->mutex); 159 159 if (ret) 160 160 return ret; 161 161
+74
drivers/gpu/drm/drm_dp_mst_topology.c
··· 294 294 memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes); 295 295 idx += req->u.i2c_write.num_bytes; 296 296 break; 297 + 298 + case DP_POWER_DOWN_PHY: 299 + case DP_POWER_UP_PHY: 300 + buf[idx] = (req->u.port_num.port_number & 0xf) << 4; 301 + idx++; 302 + break; 297 303 } 298 304 raw->cur_len = idx; 299 305 } ··· 544 538 return false; 545 539 } 546 540 541 + static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_msg_rx *raw, 542 + struct drm_dp_sideband_msg_reply_body *repmsg) 543 + { 544 + int idx = 1; 545 + 546 + repmsg->u.port_number.port_number = (raw->msg[idx] >> 4) & 0xf; 547 + idx++; 548 + if (idx > raw->curlen) { 549 + DRM_DEBUG_KMS("power up/down phy parse length fail %d %d\n", 550 + idx, raw->curlen); 551 + return false; 552 + } 553 + return true; 554 + } 555 + 547 556 static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw, 548 557 struct drm_dp_sideband_msg_reply_body *msg) 549 558 { ··· 588 567 return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg); 589 568 case DP_ALLOCATE_PAYLOAD: 590 569 return drm_dp_sideband_parse_allocate_payload_ack(raw, msg); 570 + case DP_POWER_DOWN_PHY: 571 + case DP_POWER_UP_PHY: 572 + return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg); 591 573 default: 592 574 DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type); 593 575 return false; ··· 712 688 req.u.allocate_payload.number_sdp_streams = number_sdp_streams; 713 689 memcpy(req.u.allocate_payload.sdp_stream_sink, sdp_stream_sink, 714 690 number_sdp_streams); 691 + drm_dp_encode_sideband_req(&req, msg); 692 + msg->path_msg = true; 693 + return 0; 694 + } 695 + 696 + static int build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg, 697 + int port_num, bool power_up) 698 + { 699 + struct drm_dp_sideband_msg_req_body req; 700 + 701 + if (power_up) 702 + req.req_type = DP_POWER_UP_PHY; 703 + else 704 + req.req_type = DP_POWER_DOWN_PHY; 705 + 706 + req.u.port_num.port_number = port_num; 715 707 drm_dp_encode_sideband_req(&req, msg); 716 708 msg->path_msg = true; 717 709 return 0; ··· 1763 1723 drm_dp_put_port(port); 1764 1724 return ret; 1765 1725 } 1726 + 1727 + int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, 1728 + struct drm_dp_mst_port *port, bool power_up) 1729 + { 1730 + struct drm_dp_sideband_msg_tx *txmsg; 1731 + int len, ret; 1732 + 1733 + port = drm_dp_get_validated_port_ref(mgr, port); 1734 + if (!port) 1735 + return -EINVAL; 1736 + 1737 + txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); 1738 + if (!txmsg) { 1739 + drm_dp_put_port(port); 1740 + return -ENOMEM; 1741 + } 1742 + 1743 + txmsg->dst = port->parent; 1744 + len = build_power_updown_phy(txmsg, port->port_num, power_up); 1745 + drm_dp_queue_down_tx(mgr, txmsg); 1746 + 1747 + ret = drm_dp_mst_wait_tx_reply(port->parent, txmsg); 1748 + if (ret > 0) { 1749 + if (txmsg->reply.reply_type == 1) 1750 + ret = -EINVAL; 1751 + else 1752 + ret = 0; 1753 + } 1754 + kfree(txmsg); 1755 + drm_dp_put_port(port); 1756 + 1757 + return ret; 1758 + } 1759 + EXPORT_SYMBOL(drm_dp_send_power_updown_phy); 1766 1760 1767 1761 static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr, 1768 1762 int id,
+15
drivers/gpu/drm/drm_edid.c
··· 1533 1533 * level, drivers must make all reasonable efforts to expose it as an I2C 1534 1534 * adapter and use drm_get_edid() instead of abusing this function. 1535 1535 * 1536 + * The EDID may be overridden using debugfs override_edid or firmare EDID 1537 + * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority 1538 + * order. Having either of them bypasses actual EDID reads. 1539 + * 1536 1540 * Return: Pointer to valid EDID or NULL if we couldn't find any. 1537 1541 */ 1538 1542 struct edid *drm_do_get_edid(struct drm_connector *connector, ··· 1546 1542 { 1547 1543 int i, j = 0, valid_extensions = 0; 1548 1544 u8 *edid, *new; 1545 + struct edid *override = NULL; 1546 + 1547 + if (connector->override_edid) 1548 + override = drm_edid_duplicate((const struct edid *) 1549 + connector->edid_blob_ptr->data); 1550 + 1551 + if (!override) 1552 + override = drm_load_edid_firmware(connector); 1553 + 1554 + if (!IS_ERR_OR_NULL(override)) 1555 + return override; 1549 1556 1550 1557 if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 1551 1558 return NULL;
+16
drivers/gpu/drm/drm_edid_load.c
··· 31 31 MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob " 32 32 "from built-in data or /lib/firmware instead. "); 33 33 34 + /* Use only for backward compatibility with drm_kms_helper.edid_firmware */ 35 + int __drm_set_edid_firmware_path(const char *path) 36 + { 37 + scnprintf(edid_firmware, sizeof(edid_firmware), "%s", path); 38 + 39 + return 0; 40 + } 41 + EXPORT_SYMBOL(__drm_set_edid_firmware_path); 42 + 43 + /* Use only for backward compatibility with drm_kms_helper.edid_firmware */ 44 + int __drm_get_edid_firmware_path(char *buf, size_t bufsize) 45 + { 46 + return scnprintf(buf, bufsize, "%s", edid_firmware); 47 + } 48 + EXPORT_SYMBOL(__drm_get_edid_firmware_path); 49 + 34 50 #define GENERIC_EDIDS 6 35 51 static const char * const generic_edid_name[GENERIC_EDIDS] = { 36 52 "edid/800x600.bin",
+3 -3
drivers/gpu/drm/drm_fb_helper.c
··· 910 910 if (!drm_fbdev_emulation || !fb_helper) 911 911 return; 912 912 913 + cancel_work_sync(&fb_helper->resume_work); 914 + cancel_work_sync(&fb_helper->dirty_work); 915 + 913 916 info = fb_helper->fbdev; 914 917 if (info) { 915 918 if (info->cmap.len) ··· 920 917 framebuffer_release(info); 921 918 } 922 919 fb_helper->fbdev = NULL; 923 - 924 - cancel_work_sync(&fb_helper->resume_work); 925 - cancel_work_sync(&fb_helper->dirty_work); 926 920 927 921 mutex_lock(&kernel_fb_helper_lock); 928 922 if (!list_empty(&fb_helper->kernel_fb_list)) {
+6
drivers/gpu/drm/drm_gem.c
··· 334 334 if (!obj) 335 335 return -ENOENT; 336 336 337 + /* Don't allow imported objects to be mapped */ 338 + if (obj->import_attach) { 339 + ret = -EINVAL; 340 + goto out; 341 + } 342 + 337 343 ret = drm_gem_create_mmap_offset(obj); 338 344 if (ret) 339 345 goto out;
+2 -2
drivers/gpu/drm/drm_gem_framebuffer_helper.c
··· 154 154 155 155 objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]); 156 156 if (!objs[i]) { 157 - DRM_DEV_ERROR(dev->dev, "Failed to lookup GEM\n"); 157 + DRM_DEBUG_KMS("Failed to lookup GEM object\n"); 158 158 ret = -ENOENT; 159 159 goto err_gem_object_put; 160 160 } ··· 232 232 struct dma_buf *dma_buf; 233 233 struct dma_fence *fence; 234 234 235 - if ((plane->state->fb == state->fb) || !state->fb) 235 + if (plane->state->fb == state->fb || !state->fb) 236 236 return 0; 237 237 238 238 dma_buf = drm_gem_fb_get_obj(state->fb, 0)->dma_buf;
+28
drivers/gpu/drm/drm_kms_helper_common.c
··· 26 26 */ 27 27 28 28 #include <linux/module.h> 29 + #include <drm/drmP.h> 29 30 30 31 #include "drm_crtc_helper_internal.h" 31 32 32 33 MODULE_AUTHOR("David Airlie, Jesse Barnes"); 33 34 MODULE_DESCRIPTION("DRM KMS helper"); 34 35 MODULE_LICENSE("GPL and additional rights"); 36 + 37 + #if IS_ENABLED(CONFIG_DRM_LOAD_EDID_FIRMWARE) 38 + 39 + /* Backward compatibility for drm_kms_helper.edid_firmware */ 40 + static int edid_firmware_set(const char *val, const struct kernel_param *kp) 41 + { 42 + DRM_NOTE("drm_kms_firmware.edid_firmware is deprecated, please use drm.edid_firmware intead.\n"); 43 + 44 + return __drm_set_edid_firmware_path(val); 45 + } 46 + 47 + static int edid_firmware_get(char *buffer, const struct kernel_param *kp) 48 + { 49 + return __drm_get_edid_firmware_path(buffer, PAGE_SIZE); 50 + } 51 + 52 + static const struct kernel_param_ops edid_firmware_ops = { 53 + .set = edid_firmware_set, 54 + .get = edid_firmware_get, 55 + }; 56 + 57 + module_param_cb(edid_firmware, &edid_firmware_ops, NULL, 0644); 58 + __MODULE_PARM_TYPE(edid_firmware, "charp"); 59 + MODULE_PARM_DESC(edid_firmware, 60 + "DEPRECATED. Use drm.edid_firmware module parameter instead."); 61 + 62 + #endif 35 63 36 64 static int __init drm_kms_helper_init(void) 37 65 {
+3 -2
drivers/gpu/drm/drm_mode_object.c
··· 247 247 } 248 248 EXPORT_SYMBOL(drm_object_property_set_value); 249 249 250 - int __drm_object_property_get_value(struct drm_mode_object *obj, 251 - struct drm_property *property, uint64_t *val) 250 + static int __drm_object_property_get_value(struct drm_mode_object *obj, 251 + struct drm_property *property, 252 + uint64_t *val) 252 253 { 253 254 int i; 254 255
+48 -48
drivers/gpu/drm/drm_modeset_lock.c
··· 39 39 * 40 40 * The basic usage pattern is to:: 41 41 * 42 - * drm_modeset_acquire_init(&ctx) 42 + * drm_modeset_acquire_init(ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE) 43 43 * retry: 44 44 * foreach (lock in random_ordered_set_of_locks) { 45 - * ret = drm_modeset_lock(lock, &ctx) 45 + * ret = drm_modeset_lock(lock, ctx) 46 46 * if (ret == -EDEADLK) { 47 - * drm_modeset_backoff(&ctx); 48 - * goto retry; 47 + * ret = drm_modeset_backoff(ctx); 48 + * if (!ret) 49 + * goto retry; 49 50 * } 51 + * if (ret) 52 + * goto out; 50 53 * } 51 54 * ... do stuff ... 52 - * drm_modeset_drop_locks(&ctx); 53 - * drm_modeset_acquire_fini(&ctx); 55 + * out: 56 + * drm_modeset_drop_locks(ctx); 57 + * drm_modeset_acquire_fini(ctx); 54 58 * 55 59 * If all that is needed is a single modeset lock, then the &struct 56 60 * drm_modeset_acquire_ctx is not needed and the locking can be simplified 57 - * by passing a NULL instead of ctx in the drm_modeset_lock() 58 - * call and, when done, by calling drm_modeset_unlock(). 61 + * by passing a NULL instead of ctx in the drm_modeset_lock() call or 62 + * calling drm_modeset_lock_single_interruptible(). To unlock afterwards 63 + * call drm_modeset_unlock(). 59 64 * 60 65 * On top of these per-object locks using &ww_mutex there's also an overall 61 66 * &drm_mode_config.mutex, for protecting everything else. Mostly this means ··· 183 178 /** 184 179 * drm_modeset_acquire_init - initialize acquire context 185 180 * @ctx: the acquire context 186 - * @flags: for future 181 + * @flags: 0 or %DRM_MODESET_ACQUIRE_INTERRUPTIBLE 182 + * 183 + * When passing %DRM_MODESET_ACQUIRE_INTERRUPTIBLE to @flags, 184 + * all calls to drm_modeset_lock() will perform an interruptible 185 + * wait. 187 186 */ 188 187 void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx, 189 188 uint32_t flags) ··· 195 186 memset(ctx, 0, sizeof(*ctx)); 196 187 ww_acquire_init(&ctx->ww_ctx, &crtc_ww_class); 197 188 INIT_LIST_HEAD(&ctx->locked); 189 + 190 + if (flags & DRM_MODESET_ACQUIRE_INTERRUPTIBLE) 191 + ctx->interruptible = true; 198 192 } 199 193 EXPORT_SYMBOL(drm_modeset_acquire_init); 200 194 ··· 273 261 return ret; 274 262 } 275 263 276 - static int modeset_backoff(struct drm_modeset_acquire_ctx *ctx, 277 - bool interruptible) 264 + /** 265 + * drm_modeset_backoff - deadlock avoidance backoff 266 + * @ctx: the acquire context 267 + * 268 + * If deadlock is detected (ie. drm_modeset_lock() returns -EDEADLK), 269 + * you must call this function to drop all currently held locks and 270 + * block until the contended lock becomes available. 271 + * 272 + * This function returns 0 on success, or -ERESTARTSYS if this context 273 + * is initialized with %DRM_MODESET_ACQUIRE_INTERRUPTIBLE and the 274 + * wait has been interrupted. 275 + */ 276 + int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx) 278 277 { 279 278 struct drm_modeset_lock *contended = ctx->contended; 280 279 ··· 296 273 297 274 drm_modeset_drop_locks(ctx); 298 275 299 - return modeset_lock(contended, ctx, interruptible, true); 300 - } 301 - 302 - /** 303 - * drm_modeset_backoff - deadlock avoidance backoff 304 - * @ctx: the acquire context 305 - * 306 - * If deadlock is detected (ie. drm_modeset_lock() returns -EDEADLK), 307 - * you must call this function to drop all currently held locks and 308 - * block until the contended lock becomes available. 309 - */ 310 - void drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx) 311 - { 312 - modeset_backoff(ctx, false); 276 + return modeset_lock(contended, ctx, ctx->interruptible, true); 313 277 } 314 278 EXPORT_SYMBOL(drm_modeset_backoff); 315 - 316 - /** 317 - * drm_modeset_backoff_interruptible - deadlock avoidance backoff 318 - * @ctx: the acquire context 319 - * 320 - * Interruptible version of drm_modeset_backoff() 321 - */ 322 - int drm_modeset_backoff_interruptible(struct drm_modeset_acquire_ctx *ctx) 323 - { 324 - return modeset_backoff(ctx, true); 325 - } 326 - EXPORT_SYMBOL(drm_modeset_backoff_interruptible); 327 279 328 280 /** 329 281 * drm_modeset_lock_init - initialize lock ··· 322 324 * deadlock scenario has been detected and it is an error to attempt 323 325 * to take any more locks without first calling drm_modeset_backoff(). 324 326 * 327 + * If the @ctx is not NULL and initialized with 328 + * %DRM_MODESET_ACQUIRE_INTERRUPTIBLE, this function will fail with 329 + * -ERESTARTSYS when interrupted. 330 + * 325 331 * If @ctx is NULL then the function call behaves like a normal, 326 - * non-nesting mutex_lock() call. 332 + * uninterruptible non-nesting mutex_lock() call. 327 333 */ 328 334 int drm_modeset_lock(struct drm_modeset_lock *lock, 329 335 struct drm_modeset_acquire_ctx *ctx) 330 336 { 331 337 if (ctx) 332 - return modeset_lock(lock, ctx, false, false); 338 + return modeset_lock(lock, ctx, ctx->interruptible, false); 333 339 334 340 ww_mutex_lock(&lock->mutex, NULL); 335 341 return 0; ··· 341 339 EXPORT_SYMBOL(drm_modeset_lock); 342 340 343 341 /** 344 - * drm_modeset_lock_interruptible - take modeset lock 342 + * drm_modeset_lock_single_interruptible - take a single modeset lock 345 343 * @lock: lock to take 346 - * @ctx: acquire ctx 347 344 * 348 - * Interruptible version of drm_modeset_lock() 345 + * This function behaves as drm_modeset_lock() with a NULL context, 346 + * but performs interruptible waits. 347 + * 348 + * This function returns 0 on success, or -ERESTARTSYS when interrupted. 349 349 */ 350 - int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, 351 - struct drm_modeset_acquire_ctx *ctx) 350 + int drm_modeset_lock_single_interruptible(struct drm_modeset_lock *lock) 352 351 { 353 - if (ctx) 354 - return modeset_lock(lock, ctx, true, false); 355 - 356 352 return ww_mutex_lock_interruptible(&lock->mutex, NULL); 357 353 } 358 - EXPORT_SYMBOL(drm_modeset_lock_interruptible); 354 + EXPORT_SYMBOL(drm_modeset_lock_single_interruptible); 359 355 360 356 /** 361 357 * drm_modeset_unlock - drop modeset lock
+12 -9
drivers/gpu/drm/drm_plane.c
··· 667 667 struct drm_modeset_acquire_ctx ctx; 668 668 int ret; 669 669 670 - drm_modeset_acquire_init(&ctx, 0); 670 + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 671 671 retry: 672 672 ret = drm_modeset_lock_all_ctx(plane->dev, &ctx); 673 673 if (ret) ··· 678 678 679 679 fail: 680 680 if (ret == -EDEADLK) { 681 - drm_modeset_backoff(&ctx); 682 - goto retry; 681 + ret = drm_modeset_backoff(&ctx); 682 + if (!ret) 683 + goto retry; 683 684 } 684 685 drm_modeset_drop_locks(&ctx); 685 686 drm_modeset_acquire_fini(&ctx); ··· 835 834 return -ENOENT; 836 835 } 837 836 838 - drm_modeset_acquire_init(&ctx, 0); 837 + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 839 838 retry: 840 839 ret = drm_modeset_lock(&crtc->mutex, &ctx); 841 840 if (ret) ··· 877 876 } 878 877 out: 879 878 if (ret == -EDEADLK) { 880 - drm_modeset_backoff(&ctx); 881 - goto retry; 879 + ret = drm_modeset_backoff(&ctx); 880 + if (!ret) 881 + goto retry; 882 882 } 883 883 884 884 drm_modeset_drop_locks(&ctx); ··· 987 985 return -EINVAL; 988 986 } 989 987 990 - drm_modeset_acquire_init(&ctx, 0); 988 + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 991 989 retry: 992 990 ret = drm_modeset_lock(&crtc->mutex, &ctx); 993 991 if (ret) ··· 1076 1074 crtc->primary->old_fb = NULL; 1077 1075 1078 1076 if (ret == -EDEADLK) { 1079 - drm_modeset_backoff(&ctx); 1080 - goto retry; 1077 + ret = drm_modeset_backoff(&ctx); 1078 + if (!ret) 1079 + goto retry; 1081 1080 } 1082 1081 1083 1082 drm_modeset_drop_locks(&ctx);
+1 -18
drivers/gpu/drm/drm_probe_helper.c
··· 353 353 * drm_mode_probed_add(). New modes start their life with status as OK. 354 354 * Modes are added from a single source using the following priority order. 355 355 * 356 - * - debugfs 'override_edid' (used for testing only) 357 - * - firmware EDID (drm_load_edid_firmware()) 358 356 * - &drm_connector_helper_funcs.get_modes vfunc 359 357 * - if the connector status is connector_status_connected, standard 360 358 * VESA DMT modes up to 1024x768 are automatically added ··· 481 483 goto prune; 482 484 } 483 485 484 - if (connector->override_edid) { 485 - struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; 486 - 487 - count = drm_add_edid_modes(connector, edid); 488 - drm_edid_to_eld(connector, edid); 489 - } else { 490 - struct edid *edid = drm_load_edid_firmware(connector); 491 - if (!IS_ERR_OR_NULL(edid)) { 492 - drm_mode_connector_update_edid_property(connector, edid); 493 - count = drm_add_edid_modes(connector, edid); 494 - drm_edid_to_eld(connector, edid); 495 - kfree(edid); 496 - } 497 - if (count == 0) 498 - count = (*connector_funcs->get_modes)(connector); 499 - } 486 + count = (*connector_funcs->get_modes)(connector); 500 487 501 488 if (count == 0 && connector->status == connector_status_connected) 502 489 count = drm_add_modes_noedid(connector, 1024, 768);
+5 -7
drivers/gpu/drm/drm_scdc_helper.c
··· 134 134 * Returns: 135 135 * True if the scrambling is enabled, false otherwise. 136 136 */ 137 - 138 137 bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter) 139 138 { 140 139 u8 status; ··· 141 142 142 143 ret = drm_scdc_readb(adapter, SCDC_SCRAMBLER_STATUS, &status); 143 144 if (ret < 0) { 144 - DRM_ERROR("Failed to read scrambling status, error %d\n", ret); 145 + DRM_ERROR("Failed to read scrambling status: %d\n", ret); 145 146 return false; 146 147 } 147 148 ··· 161 162 * Returns: 162 163 * True if scrambling is set/reset successfully, false otherwise. 163 164 */ 164 - 165 165 bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable) 166 166 { 167 167 u8 config; ··· 168 170 169 171 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 170 172 if (ret < 0) { 171 - DRM_ERROR("Failed to read tmds config, err=%d\n", ret); 173 + DRM_ERROR("Failed to read TMDS config: %d\n", ret); 172 174 return false; 173 175 } 174 176 ··· 179 181 180 182 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config); 181 183 if (ret < 0) { 182 - DRM_ERROR("Failed to enable scrambling, error %d\n", ret); 184 + DRM_ERROR("Failed to enable scrambling: %d\n", ret); 183 185 return false; 184 186 } 185 187 ··· 223 225 224 226 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 225 227 if (ret < 0) { 226 - DRM_ERROR("Failed to read tmds config, err=%d\n", ret); 228 + DRM_ERROR("Failed to read TMDS config: %d\n", ret); 227 229 return false; 228 230 } 229 231 ··· 234 236 235 237 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config); 236 238 if (ret < 0) { 237 - DRM_ERROR("Failed to set TMDS clock ratio, error %d\n", ret); 239 + DRM_ERROR("Failed to set TMDS clock ratio: %d\n", ret); 238 240 return false; 239 241 } 240 242
+4 -4
drivers/gpu/drm/drm_syncobj.c
··· 417 417 return 0; 418 418 } 419 419 420 - int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, 421 - int fd, int handle) 420 + static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, 421 + int fd, int handle) 422 422 { 423 423 struct dma_fence *fence = sync_file_get_fence(fd); 424 424 struct drm_syncobj *syncobj; ··· 438 438 return 0; 439 439 } 440 440 441 - int drm_syncobj_export_sync_file(struct drm_file *file_private, 442 - int handle, int *p_fd) 441 + static int drm_syncobj_export_sync_file(struct drm_file *file_private, 442 + int handle, int *p_fd) 443 443 { 444 444 int ret; 445 445 struct dma_fence *fence;
+1 -1
drivers/gpu/drm/drm_trace.h
··· 61 61 62 62 /* This part must be outside protection */ 63 63 #undef TRACE_INCLUDE_PATH 64 - #define TRACE_INCLUDE_PATH . 64 + #define TRACE_INCLUDE_PATH ../../drivers/gpu/drm 65 65 #include <trace/define_trace.h>
+1 -5
drivers/gpu/drm/exynos/exynos_drm_mic.c
··· 420 420 mic->bridge.funcs = &mic_bridge_funcs; 421 421 mic->bridge.of_node = dev->of_node; 422 422 423 - ret = drm_bridge_add(&mic->bridge); 424 - if (ret) { 425 - DRM_ERROR("mic: Failed to add MIC to the global bridge list\n"); 426 - return ret; 427 - } 423 + drm_bridge_add(&mic->bridge); 428 424 429 425 pm_runtime_enable(dev); 430 426
+2 -4
drivers/gpu/drm/gma500/cdv_intel_dp.c
··· 1901 1901 1902 1902 if (is_edp(gma_encoder)) { 1903 1903 /* cdv_intel_panel_destroy_backlight(connector->dev); */ 1904 - if (intel_dp->panel_fixed_mode) { 1905 - kfree(intel_dp->panel_fixed_mode); 1906 - intel_dp->panel_fixed_mode = NULL; 1907 - } 1904 + kfree(intel_dp->panel_fixed_mode); 1905 + intel_dp->panel_fixed_mode = NULL; 1908 1906 } 1909 1907 i2c_del_adapter(&intel_dp->adapter); 1910 1908 drm_connector_unregister(connector);
+1 -1
drivers/gpu/drm/gma500/mdfld_intel_display.c
··· 99 99 /* Wait for for the pipe enable to take effect. */ 100 100 for (count = 0; count < COUNT_MAX; count++) { 101 101 temp = REG_READ(map->conf); 102 - if ((temp & PIPEACONF_PIPE_STATE) == 1) 102 + if (temp & PIPEACONF_PIPE_STATE) 103 103 break; 104 104 } 105 105 }
+1 -1
drivers/gpu/drm/i2c/ch7006_drv.c
··· 485 485 return 0; 486 486 } 487 487 488 - static struct i2c_device_id ch7006_ids[] = { 488 + static const struct i2c_device_id ch7006_ids[] = { 489 489 { "ch7006", 0 }, 490 490 { } 491 491 };
+1 -1
drivers/gpu/drm/i2c/sil164_drv.c
··· 415 415 return 0; 416 416 } 417 417 418 - static struct i2c_device_id sil164_ids[] = { 418 + static const struct i2c_device_id sil164_ids[] = { 419 419 { "sil164", 0 }, 420 420 { } 421 421 };
+1 -1
drivers/gpu/drm/i2c/tda998x_drv.c
··· 1746 1746 MODULE_DEVICE_TABLE(of, tda998x_dt_ids); 1747 1747 #endif 1748 1748 1749 - static struct i2c_device_id tda998x_ids[] = { 1749 + static const struct i2c_device_id tda998x_ids[] = { 1750 1750 { "tda998x", 0 }, 1751 1751 { } 1752 1752 };
+1 -2
drivers/gpu/drm/i915/i915_drv.h
··· 707 707 struct drm_atomic_state *old_state); 708 708 void (*crtc_disable)(struct intel_crtc_state *old_crtc_state, 709 709 struct drm_atomic_state *old_state); 710 - void (*update_crtcs)(struct drm_atomic_state *state, 711 - unsigned int *crtc_vblank_mask); 710 + void (*update_crtcs)(struct drm_atomic_state *state); 712 711 void (*audio_codec_enable)(struct drm_connector *connector, 713 712 struct intel_encoder *encoder, 714 713 const struct drm_display_mode *adjusted_mode);
+21 -84
drivers/gpu/drm/i915/intel_display.c
··· 12129 12129 return dev->driver->get_vblank_counter(dev, crtc->pipe); 12130 12130 } 12131 12131 12132 - static void intel_atomic_wait_for_vblanks(struct drm_device *dev, 12133 - struct drm_i915_private *dev_priv, 12134 - unsigned crtc_mask) 12135 - { 12136 - unsigned last_vblank_count[I915_MAX_PIPES]; 12137 - enum pipe pipe; 12138 - int ret; 12139 - 12140 - if (!crtc_mask) 12141 - return; 12142 - 12143 - for_each_pipe(dev_priv, pipe) { 12144 - struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, 12145 - pipe); 12146 - 12147 - if (!((1 << pipe) & crtc_mask)) 12148 - continue; 12149 - 12150 - ret = drm_crtc_vblank_get(&crtc->base); 12151 - if (WARN_ON(ret != 0)) { 12152 - crtc_mask &= ~(1 << pipe); 12153 - continue; 12154 - } 12155 - 12156 - last_vblank_count[pipe] = drm_crtc_vblank_count(&crtc->base); 12157 - } 12158 - 12159 - for_each_pipe(dev_priv, pipe) { 12160 - struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, 12161 - pipe); 12162 - long lret; 12163 - 12164 - if (!((1 << pipe) & crtc_mask)) 12165 - continue; 12166 - 12167 - lret = wait_event_timeout(dev->vblank[pipe].queue, 12168 - last_vblank_count[pipe] != 12169 - drm_crtc_vblank_count(&crtc->base), 12170 - msecs_to_jiffies(50)); 12171 - 12172 - WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe)); 12173 - 12174 - drm_crtc_vblank_put(&crtc->base); 12175 - } 12176 - } 12177 - 12178 - static bool needs_vblank_wait(struct intel_crtc_state *crtc_state) 12179 - { 12180 - /* fb updated, need to unpin old fb */ 12181 - if (crtc_state->fb_changed) 12182 - return true; 12183 - 12184 - /* wm changes, need vblank before final wm's */ 12185 - if (crtc_state->update_wm_post) 12186 - return true; 12187 - 12188 - if (crtc_state->wm.need_postvbl_update) 12189 - return true; 12190 - 12191 - return false; 12192 - } 12193 - 12194 12132 static void intel_update_crtc(struct drm_crtc *crtc, 12195 12133 struct drm_atomic_state *state, 12196 12134 struct drm_crtc_state *old_crtc_state, 12197 - struct drm_crtc_state *new_crtc_state, 12198 - unsigned int *crtc_vblank_mask) 12135 + struct drm_crtc_state *new_crtc_state) 12199 12136 { 12200 12137 struct drm_device *dev = crtc->dev; 12201 12138 struct drm_i915_private *dev_priv = to_i915(dev); ··· 12155 12218 } 12156 12219 12157 12220 drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); 12158 - 12159 - if (needs_vblank_wait(pipe_config)) 12160 - *crtc_vblank_mask |= drm_crtc_mask(crtc); 12161 12221 } 12162 12222 12163 - static void intel_update_crtcs(struct drm_atomic_state *state, 12164 - unsigned int *crtc_vblank_mask) 12223 + static void intel_update_crtcs(struct drm_atomic_state *state) 12165 12224 { 12166 12225 struct drm_crtc *crtc; 12167 12226 struct drm_crtc_state *old_crtc_state, *new_crtc_state; ··· 12168 12235 continue; 12169 12236 12170 12237 intel_update_crtc(crtc, state, old_crtc_state, 12171 - new_crtc_state, crtc_vblank_mask); 12238 + new_crtc_state); 12172 12239 } 12173 12240 } 12174 12241 12175 - static void skl_update_crtcs(struct drm_atomic_state *state, 12176 - unsigned int *crtc_vblank_mask) 12242 + static void skl_update_crtcs(struct drm_atomic_state *state) 12177 12243 { 12178 12244 struct drm_i915_private *dev_priv = to_i915(state->dev); 12179 12245 struct intel_atomic_state *intel_state = to_intel_atomic_state(state); ··· 12231 12299 vbl_wait = true; 12232 12300 12233 12301 intel_update_crtc(crtc, state, old_crtc_state, 12234 - new_crtc_state, crtc_vblank_mask); 12302 + new_crtc_state); 12235 12303 12236 12304 if (vbl_wait) 12237 12305 intel_wait_for_vblank(dev_priv, pipe); ··· 12293 12361 struct intel_crtc_state *intel_cstate; 12294 12362 bool hw_check = intel_state->modeset; 12295 12363 u64 put_domains[I915_MAX_PIPES] = {}; 12296 - unsigned crtc_vblank_mask = 0; 12297 12364 int i; 12298 12365 12299 12366 intel_atomic_commit_fence_wait(intel_state); ··· 12382 12451 } 12383 12452 12384 12453 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 12385 - dev_priv->display.update_crtcs(state, &crtc_vblank_mask); 12454 + dev_priv->display.update_crtcs(state); 12386 12455 12387 12456 /* FIXME: We should call drm_atomic_helper_commit_hw_done() here 12388 12457 * already, but still need the state for the delayed optimization. To ··· 12393 12462 * - switch over to the vblank wait helper in the core after that since 12394 12463 * we don't need out special handling any more. 12395 12464 */ 12396 - if (!state->legacy_cursor_update) 12397 - intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask); 12465 + drm_atomic_helper_wait_for_flip_done(dev, state); 12398 12466 12399 12467 /* 12400 12468 * Now that the vblank has passed, we can go ahead and program the ··· 12991 13061 goto slow; 12992 13062 12993 13063 old_plane_state = plane->state; 13064 + /* 13065 + * Don't do an async update if there is an outstanding commit modifying 13066 + * the plane. This prevents our async update's changes from getting 13067 + * overridden by a previous synchronous update's state. 13068 + */ 13069 + if (old_plane_state->commit && 13070 + !try_wait_for_completion(&old_plane_state->commit->hw_done)) 13071 + goto slow; 12994 13072 12995 13073 /* 12996 13074 * If any parameters change that may affect watermarks, ··· 13058 13120 } 13059 13121 13060 13122 old_fb = old_plane_state->fb; 13061 - old_vma = to_intel_plane_state(old_plane_state)->vma; 13062 13123 13063 13124 i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb), 13064 13125 intel_plane->frontbuffer_bit); 13065 13126 13066 13127 /* Swap plane state */ 13067 - new_plane_state->fence = old_plane_state->fence; 13068 - *to_intel_plane_state(old_plane_state) = *to_intel_plane_state(new_plane_state); 13069 - new_plane_state->fence = NULL; 13070 - new_plane_state->fb = old_fb; 13071 - to_intel_plane_state(new_plane_state)->vma = NULL; 13128 + plane->state = new_plane_state; 13072 13129 13073 13130 if (plane->state->visible) { 13074 13131 trace_intel_update_plane(plane, to_intel_crtc(crtc)); ··· 13075 13142 intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc)); 13076 13143 } 13077 13144 13145 + old_vma = fetch_and_zero(&to_intel_plane_state(old_plane_state)->vma); 13078 13146 if (old_vma) 13079 13147 intel_unpin_fb_vma(old_vma); 13080 13148 13081 13149 out_unlock: 13082 13150 mutex_unlock(&dev_priv->drm.struct_mutex); 13083 13151 out_free: 13084 - intel_plane_destroy_state(plane, new_plane_state); 13152 + if (ret) 13153 + intel_plane_destroy_state(plane, new_plane_state); 13154 + else 13155 + intel_plane_destroy_state(plane, old_plane_state); 13085 13156 return ret; 13086 13157 13087 13158 slow:
+2 -1
drivers/gpu/drm/imx/imx-drm-core.c
··· 24 24 #include <drm/drm_fb_helper.h> 25 25 #include <drm/drm_crtc_helper.h> 26 26 #include <drm/drm_gem_cma_helper.h> 27 + #include <drm/drm_gem_framebuffer_helper.h> 27 28 #include <drm/drm_fb_cma_helper.h> 28 29 #include <drm/drm_plane_helper.h> 29 30 #include <drm/drm_of.h> ··· 106 105 } 107 106 108 107 static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { 109 - .fb_create = drm_fb_cma_create, 108 + .fb_create = drm_gem_fb_create, 110 109 .output_poll_changed = imx_drm_output_poll_changed, 111 110 .atomic_check = imx_drm_atomic_check, 112 111 .atomic_commit = drm_atomic_helper_commit,
+2 -1
drivers/gpu/drm/imx/ipuv3-plane.c
··· 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_fb_cma_helper.h> 20 20 #include <drm/drm_gem_cma_helper.h> 21 + #include <drm/drm_gem_framebuffer_helper.h> 21 22 #include <drm/drm_plane_helper.h> 22 23 23 24 #include "video/imx-ipu-v3.h" ··· 691 690 } 692 691 693 692 static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = { 694 - .prepare_fb = drm_fb_cma_prepare_fb, 693 + .prepare_fb = drm_gem_fb_prepare_fb, 695 694 .atomic_check = ipu_plane_atomic_check, 696 695 .atomic_disable = ipu_plane_atomic_disable, 697 696 .atomic_update = ipu_plane_atomic_update,
+1 -5
drivers/gpu/drm/mediatek/mtk_hdmi.c
··· 1696 1696 1697 1697 hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs; 1698 1698 hdmi->bridge.of_node = pdev->dev.of_node; 1699 - ret = drm_bridge_add(&hdmi->bridge); 1700 - if (ret) { 1701 - dev_err(dev, "failed to add bridge, ret = %d\n", ret); 1702 - return ret; 1703 - } 1699 + drm_bridge_add(&hdmi->bridge); 1704 1700 1705 1701 ret = mtk_hdmi_clk_enable_audio(hdmi); 1706 1702 if (ret) {
+25
drivers/gpu/drm/panel/Kconfig
··· 63 63 Say Y here if you want to enable support for LG4573 RGB panel. 64 64 To compile this driver as a module, choose M here. 65 65 66 + config DRM_PANEL_ORISETECH_OTM8009A 67 + tristate "Orise Technology otm8009a 480x800 dsi 2dl panel" 68 + depends on OF 69 + depends on DRM_MIPI_DSI 70 + depends on BACKLIGHT_CLASS_DEVICE 71 + help 72 + Say Y here if you want to enable support for Orise Technology 73 + otm8009a 480x800 dsi 2dl panel. 74 + 66 75 config DRM_PANEL_PANASONIC_VVX10F034N00 67 76 tristate "Panasonic VVX10F034N00 1920x1200 video mode panel" 68 77 depends on OF ··· 89 80 depends on BACKLIGHT_CLASS_DEVICE 90 81 select VIDEOMODE_HELPERS 91 82 83 + config DRM_PANEL_SAMSUNG_S6E63J0X03 84 + tristate "Samsung S6E63J0X03 DSI command mode panel" 85 + depends on OF 86 + depends on DRM_MIPI_DSI 87 + depends on BACKLIGHT_CLASS_DEVICE 88 + select VIDEOMODE_HELPERS 89 + 92 90 config DRM_PANEL_SAMSUNG_S6E8AA0 93 91 tristate "Samsung S6E8AA0 DSI video mode panel" 94 92 depends on OF 95 93 select DRM_MIPI_DSI 96 94 select VIDEOMODE_HELPERS 95 + 96 + config DRM_PANEL_SEIKO_43WVF1G 97 + tristate "Seiko 43WVF1G panel" 98 + depends on OF 99 + depends on BACKLIGHT_CLASS_DEVICE 100 + select VIDEOMODE_HELPERS 101 + help 102 + Say Y here if you want to enable support for the Seiko 103 + 43WVF1G controller for 800x480 LCD panels 97 104 98 105 config DRM_PANEL_SHARP_LQ101R1SX01 99 106 tristate "Sharp LQ101R1SX01 panel"
+3
drivers/gpu/drm/panel/Makefile
··· 3 3 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o 4 4 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o 5 5 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o 6 + obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o 6 7 obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o 7 8 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 8 9 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o 10 + obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o 9 11 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o 12 + obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o 10 13 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o 11 14 obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o 12 15 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
+491
drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
··· 1 + /* 2 + * Copyright (C) STMicroelectronics SA 2017 3 + * 4 + * Authors: Philippe Cornu <philippe.cornu@st.com> 5 + * Yannick Fertre <yannick.fertre@st.com> 6 + * 7 + * License terms: GNU General Public License (GPL), version 2 8 + */ 9 + #include <drm/drmP.h> 10 + #include <drm/drm_mipi_dsi.h> 11 + #include <drm/drm_panel.h> 12 + #include <linux/backlight.h> 13 + #include <linux/gpio/consumer.h> 14 + #include <video/mipi_display.h> 15 + 16 + #define DRV_NAME "orisetech_otm8009a" 17 + 18 + #define OTM8009A_BACKLIGHT_DEFAULT 240 19 + #define OTM8009A_BACKLIGHT_MAX 255 20 + 21 + /* Manufacturer Command Set */ 22 + #define MCS_ADRSFT 0x0000 /* Address Shift Function */ 23 + #define MCS_PANSET 0xB3A6 /* Panel Type Setting */ 24 + #define MCS_SD_CTRL 0xC0A2 /* Source Driver Timing Setting */ 25 + #define MCS_P_DRV_M 0xC0B4 /* Panel Driving Mode */ 26 + #define MCS_OSC_ADJ 0xC181 /* Oscillator Adjustment for Idle/Normal mode */ 27 + #define MCS_RGB_VID_SET 0xC1A1 /* RGB Video Mode Setting */ 28 + #define MCS_SD_PCH_CTRL 0xC480 /* Source Driver Precharge Control */ 29 + #define MCS_NO_DOC1 0xC48A /* Command not documented */ 30 + #define MCS_PWR_CTRL1 0xC580 /* Power Control Setting 1 */ 31 + #define MCS_PWR_CTRL2 0xC590 /* Power Control Setting 2 for Normal Mode */ 32 + #define MCS_PWR_CTRL4 0xC5B0 /* Power Control Setting 4 for DC Voltage */ 33 + #define MCS_PANCTRLSET1 0xCB80 /* Panel Control Setting 1 */ 34 + #define MCS_PANCTRLSET2 0xCB90 /* Panel Control Setting 2 */ 35 + #define MCS_PANCTRLSET3 0xCBA0 /* Panel Control Setting 3 */ 36 + #define MCS_PANCTRLSET4 0xCBB0 /* Panel Control Setting 4 */ 37 + #define MCS_PANCTRLSET5 0xCBC0 /* Panel Control Setting 5 */ 38 + #define MCS_PANCTRLSET6 0xCBD0 /* Panel Control Setting 6 */ 39 + #define MCS_PANCTRLSET7 0xCBE0 /* Panel Control Setting 7 */ 40 + #define MCS_PANCTRLSET8 0xCBF0 /* Panel Control Setting 8 */ 41 + #define MCS_PANU2D1 0xCC80 /* Panel U2D Setting 1 */ 42 + #define MCS_PANU2D2 0xCC90 /* Panel U2D Setting 2 */ 43 + #define MCS_PANU2D3 0xCCA0 /* Panel U2D Setting 3 */ 44 + #define MCS_PAND2U1 0xCCB0 /* Panel D2U Setting 1 */ 45 + #define MCS_PAND2U2 0xCCC0 /* Panel D2U Setting 2 */ 46 + #define MCS_PAND2U3 0xCCD0 /* Panel D2U Setting 3 */ 47 + #define MCS_GOAVST 0xCE80 /* GOA VST Setting */ 48 + #define MCS_GOACLKA1 0xCEA0 /* GOA CLKA1 Setting */ 49 + #define MCS_GOACLKA3 0xCEB0 /* GOA CLKA3 Setting */ 50 + #define MCS_GOAECLK 0xCFC0 /* GOA ECLK Setting */ 51 + #define MCS_NO_DOC2 0xCFD0 /* Command not documented */ 52 + #define MCS_GVDDSET 0xD800 /* GVDD/NGVDD */ 53 + #define MCS_VCOMDC 0xD900 /* VCOM Voltage Setting */ 54 + #define MCS_GMCT2_2P 0xE100 /* Gamma Correction 2.2+ Setting */ 55 + #define MCS_GMCT2_2N 0xE200 /* Gamma Correction 2.2- Setting */ 56 + #define MCS_NO_DOC3 0xF5B6 /* Command not documented */ 57 + #define MCS_CMD2_ENA1 0xFF00 /* Enable Access Command2 "CMD2" */ 58 + #define MCS_CMD2_ENA2 0xFF80 /* Enable Access Orise Command2 */ 59 + 60 + struct otm8009a { 61 + struct device *dev; 62 + struct drm_panel panel; 63 + struct backlight_device *bl_dev; 64 + struct gpio_desc *reset_gpio; 65 + bool prepared; 66 + bool enabled; 67 + }; 68 + 69 + static const struct drm_display_mode default_mode = { 70 + .clock = 32729, 71 + .hdisplay = 480, 72 + .hsync_start = 480 + 120, 73 + .hsync_end = 480 + 120 + 63, 74 + .htotal = 480 + 120 + 63 + 120, 75 + .vdisplay = 800, 76 + .vsync_start = 800 + 12, 77 + .vsync_end = 800 + 12 + 12, 78 + .vtotal = 800 + 12 + 12 + 12, 79 + .vrefresh = 50, 80 + .flags = 0, 81 + .width_mm = 52, 82 + .height_mm = 86, 83 + }; 84 + 85 + static inline struct otm8009a *panel_to_otm8009a(struct drm_panel *panel) 86 + { 87 + return container_of(panel, struct otm8009a, panel); 88 + } 89 + 90 + static void otm8009a_dcs_write_buf(struct otm8009a *ctx, const void *data, 91 + size_t len) 92 + { 93 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 94 + 95 + if (mipi_dsi_dcs_write_buffer(dsi, data, len) < 0) 96 + DRM_WARN("mipi dsi dcs write buffer failed\n"); 97 + } 98 + 99 + #define dcs_write_seq(ctx, seq...) \ 100 + ({ \ 101 + static const u8 d[] = { seq }; \ 102 + otm8009a_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \ 103 + }) 104 + 105 + #define dcs_write_cmd_at(ctx, cmd, seq...) \ 106 + ({ \ 107 + dcs_write_seq(ctx, MCS_ADRSFT, (cmd) & 0xFF); \ 108 + dcs_write_seq(ctx, (cmd) >> 8, seq); \ 109 + }) 110 + 111 + static int otm8009a_init_sequence(struct otm8009a *ctx) 112 + { 113 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 114 + int ret; 115 + 116 + /* Enter CMD2 */ 117 + dcs_write_cmd_at(ctx, MCS_CMD2_ENA1, 0x80, 0x09, 0x01); 118 + 119 + /* Enter Orise Command2 */ 120 + dcs_write_cmd_at(ctx, MCS_CMD2_ENA2, 0x80, 0x09); 121 + 122 + dcs_write_cmd_at(ctx, MCS_SD_PCH_CTRL, 0x30); 123 + mdelay(10); 124 + 125 + dcs_write_cmd_at(ctx, MCS_NO_DOC1, 0x40); 126 + mdelay(10); 127 + 128 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL4 + 1, 0xA9); 129 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 1, 0x34); 130 + dcs_write_cmd_at(ctx, MCS_P_DRV_M, 0x50); 131 + dcs_write_cmd_at(ctx, MCS_VCOMDC, 0x4E); 132 + dcs_write_cmd_at(ctx, MCS_OSC_ADJ, 0x66); /* 65Hz */ 133 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 2, 0x01); 134 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 5, 0x34); 135 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 4, 0x33); 136 + dcs_write_cmd_at(ctx, MCS_GVDDSET, 0x79, 0x79); 137 + dcs_write_cmd_at(ctx, MCS_SD_CTRL + 1, 0x1B); 138 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL1 + 2, 0x83); 139 + dcs_write_cmd_at(ctx, MCS_SD_PCH_CTRL + 1, 0x83); 140 + dcs_write_cmd_at(ctx, MCS_RGB_VID_SET, 0x0E); 141 + dcs_write_cmd_at(ctx, MCS_PANSET, 0x00, 0x01); 142 + 143 + dcs_write_cmd_at(ctx, MCS_GOAVST, 0x85, 0x01, 0x00, 0x84, 0x01, 0x00); 144 + dcs_write_cmd_at(ctx, MCS_GOACLKA1, 0x18, 0x04, 0x03, 0x39, 0x00, 0x00, 145 + 0x00, 0x18, 0x03, 0x03, 0x3A, 0x00, 0x00, 0x00); 146 + dcs_write_cmd_at(ctx, MCS_GOACLKA3, 0x18, 0x02, 0x03, 0x3B, 0x00, 0x00, 147 + 0x00, 0x18, 0x01, 0x03, 0x3C, 0x00, 0x00, 0x00); 148 + dcs_write_cmd_at(ctx, MCS_GOAECLK, 0x01, 0x01, 0x20, 0x20, 0x00, 0x00, 149 + 0x01, 0x02, 0x00, 0x00); 150 + 151 + dcs_write_cmd_at(ctx, MCS_NO_DOC2, 0x00); 152 + 153 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 154 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155 + 0, 0, 0, 0, 0); 156 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157 + 0, 0, 0, 0, 0); 158 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 159 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET5, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 160 + 0, 0, 0, 0, 0); 161 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET6, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 162 + 4, 0, 0, 0, 0); 163 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 164 + dcs_write_cmd_at(ctx, MCS_PANCTRLSET8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 165 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); 166 + 167 + dcs_write_cmd_at(ctx, MCS_PANU2D1, 0x00, 0x26, 0x09, 0x0B, 0x01, 0x25, 168 + 0x00, 0x00, 0x00, 0x00); 169 + dcs_write_cmd_at(ctx, MCS_PANU2D2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x0A, 0x0C, 0x02); 171 + dcs_write_cmd_at(ctx, MCS_PANU2D3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 172 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 173 + dcs_write_cmd_at(ctx, MCS_PAND2U1, 0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26, 174 + 0x00, 0x00, 0x00, 0x00); 175 + dcs_write_cmd_at(ctx, MCS_PAND2U2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x0B, 0x09, 0x01); 177 + dcs_write_cmd_at(ctx, MCS_PAND2U3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 178 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 179 + 180 + dcs_write_cmd_at(ctx, MCS_PWR_CTRL1 + 1, 0x66); 181 + 182 + dcs_write_cmd_at(ctx, MCS_NO_DOC3, 0x06); 183 + 184 + dcs_write_cmd_at(ctx, MCS_GMCT2_2P, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, 185 + 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A, 186 + 0x01); 187 + dcs_write_cmd_at(ctx, MCS_GMCT2_2N, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, 188 + 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A, 189 + 0x01); 190 + 191 + /* Exit CMD2 */ 192 + dcs_write_cmd_at(ctx, MCS_CMD2_ENA1, 0xFF, 0xFF, 0xFF); 193 + 194 + ret = mipi_dsi_dcs_nop(dsi); 195 + if (ret) 196 + return ret; 197 + 198 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 199 + if (ret) 200 + return ret; 201 + 202 + /* Wait for sleep out exit */ 203 + mdelay(120); 204 + 205 + /* Default portrait 480x800 rgb24 */ 206 + dcs_write_seq(ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); 207 + 208 + ret = mipi_dsi_dcs_set_column_address(dsi, 0, 209 + default_mode.hdisplay - 1); 210 + if (ret) 211 + return ret; 212 + 213 + ret = mipi_dsi_dcs_set_page_address(dsi, 0, default_mode.vdisplay - 1); 214 + if (ret) 215 + return ret; 216 + 217 + /* See otm8009a driver documentation for pixel format descriptions */ 218 + ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT | 219 + MIPI_DCS_PIXEL_FMT_24BIT << 4); 220 + if (ret) 221 + return ret; 222 + 223 + /* Disable CABC feature */ 224 + dcs_write_seq(ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); 225 + 226 + ret = mipi_dsi_dcs_set_display_on(dsi); 227 + if (ret) 228 + return ret; 229 + 230 + ret = mipi_dsi_dcs_nop(dsi); 231 + if (ret) 232 + return ret; 233 + 234 + /* Send Command GRAM memory write (no parameters) */ 235 + dcs_write_seq(ctx, MIPI_DCS_WRITE_MEMORY_START); 236 + 237 + return 0; 238 + } 239 + 240 + static int otm8009a_disable(struct drm_panel *panel) 241 + { 242 + struct otm8009a *ctx = panel_to_otm8009a(panel); 243 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 244 + int ret; 245 + 246 + if (!ctx->enabled) 247 + return 0; /* This is not an issue so we return 0 here */ 248 + 249 + /* Power off the backlight. Note: end-user still controls brightness */ 250 + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; 251 + ret = backlight_update_status(ctx->bl_dev); 252 + if (ret) 253 + return ret; 254 + 255 + ret = mipi_dsi_dcs_set_display_off(dsi); 256 + if (ret) 257 + return ret; 258 + 259 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 260 + if (ret) 261 + return ret; 262 + 263 + msleep(120); 264 + 265 + ctx->enabled = false; 266 + 267 + return 0; 268 + } 269 + 270 + static int otm8009a_unprepare(struct drm_panel *panel) 271 + { 272 + struct otm8009a *ctx = panel_to_otm8009a(panel); 273 + 274 + if (!ctx->prepared) 275 + return 0; 276 + 277 + if (ctx->reset_gpio) { 278 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 279 + msleep(20); 280 + } 281 + 282 + ctx->prepared = false; 283 + 284 + return 0; 285 + } 286 + 287 + static int otm8009a_prepare(struct drm_panel *panel) 288 + { 289 + struct otm8009a *ctx = panel_to_otm8009a(panel); 290 + int ret; 291 + 292 + if (ctx->prepared) 293 + return 0; 294 + 295 + if (ctx->reset_gpio) { 296 + gpiod_set_value_cansleep(ctx->reset_gpio, 0); 297 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 298 + msleep(20); 299 + gpiod_set_value_cansleep(ctx->reset_gpio, 0); 300 + msleep(100); 301 + } 302 + 303 + ret = otm8009a_init_sequence(ctx); 304 + if (ret) 305 + return ret; 306 + 307 + ctx->prepared = true; 308 + 309 + /* 310 + * Power on the backlight. Note: end-user still controls brightness 311 + * Note: ctx->prepared must be true before updating the backlight. 312 + */ 313 + ctx->bl_dev->props.power = FB_BLANK_UNBLANK; 314 + backlight_update_status(ctx->bl_dev); 315 + 316 + return 0; 317 + } 318 + 319 + static int otm8009a_enable(struct drm_panel *panel) 320 + { 321 + struct otm8009a *ctx = panel_to_otm8009a(panel); 322 + 323 + ctx->enabled = true; 324 + 325 + return 0; 326 + } 327 + 328 + static int otm8009a_get_modes(struct drm_panel *panel) 329 + { 330 + struct drm_display_mode *mode; 331 + 332 + mode = drm_mode_duplicate(panel->drm, &default_mode); 333 + if (!mode) { 334 + DRM_ERROR("failed to add mode %ux%ux@%u\n", 335 + default_mode.hdisplay, default_mode.vdisplay, 336 + default_mode.vrefresh); 337 + return -ENOMEM; 338 + } 339 + 340 + drm_mode_set_name(mode); 341 + 342 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 343 + drm_mode_probed_add(panel->connector, mode); 344 + 345 + panel->connector->display_info.width_mm = mode->width_mm; 346 + panel->connector->display_info.height_mm = mode->height_mm; 347 + 348 + return 1; 349 + } 350 + 351 + static const struct drm_panel_funcs otm8009a_drm_funcs = { 352 + .disable = otm8009a_disable, 353 + .unprepare = otm8009a_unprepare, 354 + .prepare = otm8009a_prepare, 355 + .enable = otm8009a_enable, 356 + .get_modes = otm8009a_get_modes, 357 + }; 358 + 359 + /* 360 + * DSI-BASED BACKLIGHT 361 + */ 362 + 363 + static int otm8009a_backlight_update_status(struct backlight_device *bd) 364 + { 365 + struct otm8009a *ctx = bl_get_data(bd); 366 + u8 data[2]; 367 + 368 + if (!ctx->prepared) { 369 + DRM_DEBUG("lcd not ready yet for setting its backlight!\n"); 370 + return -ENXIO; 371 + } 372 + 373 + if (bd->props.power <= FB_BLANK_NORMAL) { 374 + /* Power on the backlight with the requested brightness 375 + * Note We can not use mipi_dsi_dcs_set_display_brightness() 376 + * as otm8009a driver support only 8-bit brightness (1 param). 377 + */ 378 + data[0] = MIPI_DCS_SET_DISPLAY_BRIGHTNESS; 379 + data[1] = bd->props.brightness; 380 + otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data)); 381 + 382 + /* set Brightness Control & Backlight on */ 383 + data[1] = 0x24; 384 + 385 + } else { 386 + /* Power off the backlight: set Brightness Control & Bl off */ 387 + data[1] = 0; 388 + } 389 + 390 + /* Update Brightness Control & Backlight */ 391 + data[0] = MIPI_DCS_WRITE_CONTROL_DISPLAY; 392 + otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data)); 393 + 394 + return 0; 395 + } 396 + 397 + static const struct backlight_ops otm8009a_backlight_ops = { 398 + .update_status = otm8009a_backlight_update_status, 399 + }; 400 + 401 + static int otm8009a_probe(struct mipi_dsi_device *dsi) 402 + { 403 + struct device *dev = &dsi->dev; 404 + struct otm8009a *ctx; 405 + int ret; 406 + 407 + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 408 + if (!ctx) 409 + return -ENOMEM; 410 + 411 + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 412 + if (IS_ERR(ctx->reset_gpio)) { 413 + dev_err(dev, "cannot get reset-gpio\n"); 414 + return PTR_ERR(ctx->reset_gpio); 415 + } 416 + 417 + mipi_dsi_set_drvdata(dsi, ctx); 418 + 419 + ctx->dev = dev; 420 + 421 + dsi->lanes = 2; 422 + dsi->format = MIPI_DSI_FMT_RGB888; 423 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 424 + MIPI_DSI_MODE_LPM; 425 + 426 + drm_panel_init(&ctx->panel); 427 + ctx->panel.dev = dev; 428 + ctx->panel.funcs = &otm8009a_drm_funcs; 429 + 430 + ctx->bl_dev = backlight_device_register(DRV_NAME "_backlight", dev, ctx, 431 + &otm8009a_backlight_ops, NULL); 432 + if (IS_ERR(ctx->bl_dev)) { 433 + dev_err(dev, "failed to register backlight device\n"); 434 + return PTR_ERR(ctx->bl_dev); 435 + } 436 + 437 + ctx->bl_dev->props.max_brightness = OTM8009A_BACKLIGHT_MAX; 438 + ctx->bl_dev->props.brightness = OTM8009A_BACKLIGHT_DEFAULT; 439 + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; 440 + ctx->bl_dev->props.type = BACKLIGHT_RAW; 441 + 442 + drm_panel_add(&ctx->panel); 443 + 444 + ret = mipi_dsi_attach(dsi); 445 + if (ret < 0) { 446 + dev_err(dev, "mipi_dsi_attach failed. Is host ready?\n"); 447 + drm_panel_remove(&ctx->panel); 448 + backlight_device_unregister(ctx->bl_dev); 449 + return ret; 450 + } 451 + 452 + DRM_INFO(DRV_NAME "_panel %ux%u@%u %ubpp dsi %udl - ready\n", 453 + default_mode.hdisplay, default_mode.vdisplay, 454 + default_mode.vrefresh, 455 + mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes); 456 + 457 + return 0; 458 + } 459 + 460 + static int otm8009a_remove(struct mipi_dsi_device *dsi) 461 + { 462 + struct otm8009a *ctx = mipi_dsi_get_drvdata(dsi); 463 + 464 + mipi_dsi_detach(dsi); 465 + drm_panel_remove(&ctx->panel); 466 + 467 + backlight_device_unregister(ctx->bl_dev); 468 + 469 + return 0; 470 + } 471 + 472 + static const struct of_device_id orisetech_otm8009a_of_match[] = { 473 + { .compatible = "orisetech,otm8009a" }, 474 + { } 475 + }; 476 + MODULE_DEVICE_TABLE(of, orisetech_otm8009a_of_match); 477 + 478 + static struct mipi_dsi_driver orisetech_otm8009a_driver = { 479 + .probe = otm8009a_probe, 480 + .remove = otm8009a_remove, 481 + .driver = { 482 + .name = DRV_NAME "_panel", 483 + .of_match_table = orisetech_otm8009a_of_match, 484 + }, 485 + }; 486 + module_mipi_dsi_driver(orisetech_otm8009a_driver); 487 + 488 + MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>"); 489 + MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>"); 490 + MODULE_DESCRIPTION("DRM driver for Orise Tech OTM8009A MIPI DSI panel"); 491 + MODULE_LICENSE("GPL v2");
+532
drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c
··· 1 + /* 2 + * MIPI-DSI based S6E63J0X03 AMOLED lcd 1.63 inch panel driver. 3 + * 4 + * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd 5 + * 6 + * Inki Dae <inki.dae@samsung.com> 7 + * Hoegeun Kwon <hoegeun.kwon@samsung.com> 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + 14 + #include <drm/drmP.h> 15 + #include <drm/drm_mipi_dsi.h> 16 + #include <drm/drm_panel.h> 17 + #include <linux/backlight.h> 18 + #include <linux/gpio/consumer.h> 19 + #include <linux/regulator/consumer.h> 20 + #include <video/mipi_display.h> 21 + 22 + #define MCS_LEVEL2_KEY 0xf0 23 + #define MCS_MTP_KEY 0xf1 24 + #define MCS_MTP_SET3 0xd4 25 + 26 + #define MAX_BRIGHTNESS 100 27 + #define DEFAULT_BRIGHTNESS 80 28 + 29 + #define NUM_GAMMA_STEPS 9 30 + #define GAMMA_CMD_CNT 28 31 + 32 + #define FIRST_COLUMN 20 33 + 34 + struct s6e63j0x03 { 35 + struct device *dev; 36 + struct drm_panel panel; 37 + struct backlight_device *bl_dev; 38 + 39 + struct regulator_bulk_data supplies[2]; 40 + struct gpio_desc *reset_gpio; 41 + }; 42 + 43 + static const struct drm_display_mode default_mode = { 44 + .clock = 4649, 45 + .hdisplay = 320, 46 + .hsync_start = 320 + 1, 47 + .hsync_end = 320 + 1 + 1, 48 + .htotal = 320 + 1 + 1 + 1, 49 + .vdisplay = 320, 50 + .vsync_start = 320 + 150, 51 + .vsync_end = 320 + 150 + 1, 52 + .vtotal = 320 + 150 + 1 + 2, 53 + .vrefresh = 30, 54 + .flags = 0, 55 + }; 56 + 57 + static const unsigned char gamma_tbl[NUM_GAMMA_STEPS][GAMMA_CMD_CNT] = { 58 + { /* Gamma 10 */ 59 + MCS_MTP_SET3, 60 + 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x52, 0x6b, 0x6f, 0x26, 61 + 0x28, 0x2d, 0x28, 0x26, 0x27, 0x33, 0x34, 0x32, 0x36, 0x36, 62 + 0x35, 0x00, 0xab, 0x00, 0xae, 0x00, 0xbf 63 + }, 64 + { /* gamma 30 */ 65 + MCS_MTP_SET3, 66 + 0x00, 0x00, 0x00, 0x70, 0x7f, 0x7f, 0x4e, 0x64, 0x69, 0x26, 67 + 0x27, 0x2a, 0x28, 0x29, 0x27, 0x31, 0x32, 0x31, 0x35, 0x34, 68 + 0x35, 0x00, 0xc4, 0x00, 0xca, 0x00, 0xdc 69 + }, 70 + { /* gamma 60 */ 71 + MCS_MTP_SET3, 72 + 0x00, 0x00, 0x00, 0x65, 0x7b, 0x7d, 0x5f, 0x67, 0x68, 0x2a, 73 + 0x28, 0x29, 0x28, 0x2a, 0x27, 0x31, 0x2f, 0x30, 0x34, 0x33, 74 + 0x34, 0x00, 0xd9, 0x00, 0xe4, 0x00, 0xf5 75 + }, 76 + { /* gamma 90 */ 77 + MCS_MTP_SET3, 78 + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x71, 0x67, 0x6a, 0x6c, 0x29, 79 + 0x28, 0x28, 0x28, 0x29, 0x27, 0x30, 0x2e, 0x30, 0x32, 0x31, 80 + 0x31, 0x00, 0xea, 0x00, 0xf6, 0x01, 0x09 81 + }, 82 + { /* gamma 120 */ 83 + MCS_MTP_SET3, 84 + 0x00, 0x00, 0x00, 0x3d, 0x66, 0x68, 0x69, 0x69, 0x69, 0x28, 85 + 0x28, 0x27, 0x28, 0x28, 0x27, 0x30, 0x2e, 0x2f, 0x31, 0x31, 86 + 0x30, 0x00, 0xf9, 0x01, 0x05, 0x01, 0x1b 87 + }, 88 + { /* gamma 150 */ 89 + MCS_MTP_SET3, 90 + 0x00, 0x00, 0x00, 0x31, 0x51, 0x53, 0x66, 0x66, 0x67, 0x28, 91 + 0x29, 0x27, 0x28, 0x27, 0x27, 0x2e, 0x2d, 0x2e, 0x31, 0x31, 92 + 0x30, 0x01, 0x04, 0x01, 0x11, 0x01, 0x29 93 + }, 94 + { /* gamma 200 */ 95 + MCS_MTP_SET3, 96 + 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x51, 0x67, 0x65, 0x65, 0x29, 97 + 0x2a, 0x28, 0x27, 0x25, 0x26, 0x2d, 0x2c, 0x2c, 0x30, 0x30, 98 + 0x30, 0x01, 0x14, 0x01, 0x23, 0x01, 0x3b 99 + }, 100 + { /* gamma 240 */ 101 + MCS_MTP_SET3, 102 + 0x00, 0x00, 0x00, 0x2c, 0x4d, 0x50, 0x65, 0x63, 0x64, 0x2a, 103 + 0x2c, 0x29, 0x26, 0x24, 0x25, 0x2c, 0x2b, 0x2b, 0x30, 0x30, 104 + 0x30, 0x01, 0x1e, 0x01, 0x2f, 0x01, 0x47 105 + }, 106 + { /* gamma 300 */ 107 + MCS_MTP_SET3, 108 + 0x00, 0x00, 0x00, 0x38, 0x61, 0x64, 0x65, 0x63, 0x64, 0x28, 109 + 0x2a, 0x27, 0x26, 0x23, 0x25, 0x2b, 0x2b, 0x2a, 0x30, 0x2f, 110 + 0x30, 0x01, 0x2d, 0x01, 0x3f, 0x01, 0x57 111 + } 112 + }; 113 + 114 + static inline struct s6e63j0x03 *panel_to_s6e63j0x03(struct drm_panel *panel) 115 + { 116 + return container_of(panel, struct s6e63j0x03, panel); 117 + } 118 + 119 + static inline ssize_t s6e63j0x03_dcs_write_seq(struct s6e63j0x03 *ctx, 120 + const void *seq, size_t len) 121 + { 122 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 123 + 124 + return mipi_dsi_dcs_write_buffer(dsi, seq, len); 125 + } 126 + 127 + #define s6e63j0x03_dcs_write_seq_static(ctx, seq...) \ 128 + ({ \ 129 + static const u8 d[] = { seq }; \ 130 + s6e63j0x03_dcs_write_seq(ctx, d, ARRAY_SIZE(d)); \ 131 + }) 132 + 133 + static inline int s6e63j0x03_enable_lv2_command(struct s6e63j0x03 *ctx) 134 + { 135 + return s6e63j0x03_dcs_write_seq_static(ctx, MCS_LEVEL2_KEY, 0x5a, 0x5a); 136 + } 137 + 138 + static inline int s6e63j0x03_apply_mtp_key(struct s6e63j0x03 *ctx, bool on) 139 + { 140 + if (on) 141 + return s6e63j0x03_dcs_write_seq_static(ctx, 142 + MCS_MTP_KEY, 0x5a, 0x5a); 143 + 144 + return s6e63j0x03_dcs_write_seq_static(ctx, MCS_MTP_KEY, 0xa5, 0xa5); 145 + } 146 + 147 + static int s6e63j0x03_power_on(struct s6e63j0x03 *ctx) 148 + { 149 + int ret; 150 + 151 + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); 152 + if (ret < 0) 153 + return ret; 154 + 155 + msleep(30); 156 + 157 + gpiod_set_value(ctx->reset_gpio, 1); 158 + usleep_range(1000, 2000); 159 + gpiod_set_value(ctx->reset_gpio, 0); 160 + usleep_range(5000, 6000); 161 + 162 + return 0; 163 + } 164 + 165 + static int s6e63j0x03_power_off(struct s6e63j0x03 *ctx) 166 + { 167 + return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); 168 + } 169 + 170 + static unsigned int s6e63j0x03_get_brightness_index(unsigned int brightness) 171 + { 172 + unsigned int index; 173 + 174 + index = brightness / (MAX_BRIGHTNESS / NUM_GAMMA_STEPS); 175 + 176 + if (index >= NUM_GAMMA_STEPS) 177 + index = NUM_GAMMA_STEPS - 1; 178 + 179 + return index; 180 + } 181 + 182 + static int s6e63j0x03_update_gamma(struct s6e63j0x03 *ctx, 183 + unsigned int brightness) 184 + { 185 + struct backlight_device *bl_dev = ctx->bl_dev; 186 + unsigned int index = s6e63j0x03_get_brightness_index(brightness); 187 + int ret; 188 + 189 + ret = s6e63j0x03_apply_mtp_key(ctx, true); 190 + if (ret < 0) 191 + return ret; 192 + 193 + ret = s6e63j0x03_dcs_write_seq(ctx, gamma_tbl[index], GAMMA_CMD_CNT); 194 + if (ret < 0) 195 + return ret; 196 + 197 + ret = s6e63j0x03_apply_mtp_key(ctx, false); 198 + if (ret < 0) 199 + return ret; 200 + 201 + bl_dev->props.brightness = brightness; 202 + 203 + return 0; 204 + } 205 + 206 + static int s6e63j0x03_set_brightness(struct backlight_device *bl_dev) 207 + { 208 + struct s6e63j0x03 *ctx = bl_get_data(bl_dev); 209 + unsigned int brightness = bl_dev->props.brightness; 210 + 211 + return s6e63j0x03_update_gamma(ctx, brightness); 212 + } 213 + 214 + static const struct backlight_ops s6e63j0x03_bl_ops = { 215 + .update_status = s6e63j0x03_set_brightness, 216 + }; 217 + 218 + static int s6e63j0x03_disable(struct drm_panel *panel) 219 + { 220 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 221 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 222 + int ret; 223 + 224 + ret = mipi_dsi_dcs_set_display_off(dsi); 225 + if (ret < 0) 226 + return ret; 227 + 228 + ctx->bl_dev->props.power = FB_BLANK_NORMAL; 229 + 230 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 231 + if (ret < 0) 232 + return ret; 233 + 234 + msleep(120); 235 + 236 + return 0; 237 + } 238 + 239 + static int s6e63j0x03_unprepare(struct drm_panel *panel) 240 + { 241 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 242 + int ret; 243 + 244 + ret = s6e63j0x03_power_off(ctx); 245 + if (ret < 0) 246 + return ret; 247 + 248 + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; 249 + 250 + return 0; 251 + } 252 + 253 + static int s6e63j0x03_panel_init(struct s6e63j0x03 *ctx) 254 + { 255 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 256 + int ret; 257 + 258 + ret = s6e63j0x03_enable_lv2_command(ctx); 259 + if (ret < 0) 260 + return ret; 261 + 262 + ret = s6e63j0x03_apply_mtp_key(ctx, true); 263 + if (ret < 0) 264 + return ret; 265 + 266 + /* set porch adjustment */ 267 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf2, 0x1c, 0x28); 268 + if (ret < 0) 269 + return ret; 270 + 271 + /* set frame freq */ 272 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb5, 0x00, 0x02, 0x00); 273 + if (ret < 0) 274 + return ret; 275 + 276 + /* set caset, paset */ 277 + ret = mipi_dsi_dcs_set_column_address(dsi, FIRST_COLUMN, 278 + default_mode.hdisplay - 1 + FIRST_COLUMN); 279 + if (ret < 0) 280 + return ret; 281 + 282 + ret = mipi_dsi_dcs_set_page_address(dsi, 0, default_mode.vdisplay - 1); 283 + if (ret < 0) 284 + return ret; 285 + 286 + /* set ltps timming 0, 1 */ 287 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf8, 0x08, 0x08, 0x08, 0x17, 288 + 0x00, 0x2a, 0x02, 0x26, 0x00, 0x00, 0x02, 0x00, 0x00); 289 + if (ret < 0) 290 + return ret; 291 + 292 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf7, 0x02); 293 + if (ret < 0) 294 + return ret; 295 + 296 + /* set param pos te_edge */ 297 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb0, 0x01); 298 + if (ret < 0) 299 + return ret; 300 + 301 + /* set te rising edge */ 302 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xe2, 0x0f); 303 + if (ret < 0) 304 + return ret; 305 + 306 + /* set param pos default */ 307 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb0, 0x00); 308 + if (ret < 0) 309 + return ret; 310 + 311 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 312 + if (ret < 0) 313 + return ret; 314 + 315 + ret = s6e63j0x03_apply_mtp_key(ctx, false); 316 + if (ret < 0) 317 + return ret; 318 + 319 + return 0; 320 + } 321 + 322 + static int s6e63j0x03_prepare(struct drm_panel *panel) 323 + { 324 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 325 + int ret; 326 + 327 + ret = s6e63j0x03_power_on(ctx); 328 + if (ret < 0) 329 + return ret; 330 + 331 + ret = s6e63j0x03_panel_init(ctx); 332 + if (ret < 0) 333 + goto err; 334 + 335 + ctx->bl_dev->props.power = FB_BLANK_NORMAL; 336 + 337 + return 0; 338 + 339 + err: 340 + s6e63j0x03_power_off(ctx); 341 + return ret; 342 + } 343 + 344 + static int s6e63j0x03_enable(struct drm_panel *panel) 345 + { 346 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 347 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 348 + int ret; 349 + 350 + msleep(120); 351 + 352 + ret = s6e63j0x03_apply_mtp_key(ctx, true); 353 + if (ret < 0) 354 + return ret; 355 + 356 + /* set elvss_cond */ 357 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb1, 0x00, 0x09); 358 + if (ret < 0) 359 + return ret; 360 + 361 + /* set pos */ 362 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 363 + MIPI_DCS_SET_ADDRESS_MODE, 0x40); 364 + if (ret < 0) 365 + return ret; 366 + 367 + /* set default white brightness */ 368 + ret = mipi_dsi_dcs_set_display_brightness(dsi, 0x00ff); 369 + if (ret < 0) 370 + return ret; 371 + 372 + /* set white ctrl */ 373 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 374 + MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); 375 + if (ret < 0) 376 + return ret; 377 + 378 + /* set acl off */ 379 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 380 + MIPI_DCS_WRITE_POWER_SAVE, 0x00); 381 + if (ret < 0) 382 + return ret; 383 + 384 + ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); 385 + if (ret < 0) 386 + return ret; 387 + 388 + ret = s6e63j0x03_apply_mtp_key(ctx, false); 389 + if (ret < 0) 390 + return ret; 391 + 392 + ret = mipi_dsi_dcs_set_display_on(dsi); 393 + if (ret < 0) 394 + return ret; 395 + 396 + ctx->bl_dev->props.power = FB_BLANK_UNBLANK; 397 + 398 + return 0; 399 + } 400 + 401 + static int s6e63j0x03_get_modes(struct drm_panel *panel) 402 + { 403 + struct drm_connector *connector = panel->connector; 404 + struct drm_display_mode *mode; 405 + 406 + mode = drm_mode_duplicate(panel->drm, &default_mode); 407 + if (!mode) { 408 + DRM_ERROR("failed to add mode %ux%ux@%u\n", 409 + default_mode.hdisplay, default_mode.vdisplay, 410 + default_mode.vrefresh); 411 + return -ENOMEM; 412 + } 413 + 414 + drm_mode_set_name(mode); 415 + 416 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 417 + drm_mode_probed_add(connector, mode); 418 + 419 + connector->display_info.width_mm = 29; 420 + connector->display_info.height_mm = 29; 421 + 422 + return 1; 423 + } 424 + 425 + static const struct drm_panel_funcs s6e63j0x03_funcs = { 426 + .disable = s6e63j0x03_disable, 427 + .unprepare = s6e63j0x03_unprepare, 428 + .prepare = s6e63j0x03_prepare, 429 + .enable = s6e63j0x03_enable, 430 + .get_modes = s6e63j0x03_get_modes, 431 + }; 432 + 433 + static int s6e63j0x03_probe(struct mipi_dsi_device *dsi) 434 + { 435 + struct device *dev = &dsi->dev; 436 + struct s6e63j0x03 *ctx; 437 + int ret; 438 + 439 + ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03), GFP_KERNEL); 440 + if (!ctx) 441 + return -ENOMEM; 442 + 443 + mipi_dsi_set_drvdata(dsi, ctx); 444 + 445 + ctx->dev = dev; 446 + 447 + dsi->lanes = 1; 448 + dsi->format = MIPI_DSI_FMT_RGB888; 449 + dsi->mode_flags = MIPI_DSI_MODE_EOT_PACKET; 450 + 451 + ctx->supplies[0].supply = "vdd3"; 452 + ctx->supplies[1].supply = "vci"; 453 + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), 454 + ctx->supplies); 455 + if (ret < 0) { 456 + dev_err(dev, "failed to get regulators: %d\n", ret); 457 + return ret; 458 + } 459 + 460 + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 461 + if (IS_ERR(ctx->reset_gpio)) { 462 + dev_err(dev, "cannot get reset-gpio: %ld\n", 463 + PTR_ERR(ctx->reset_gpio)); 464 + return PTR_ERR(ctx->reset_gpio); 465 + } 466 + 467 + drm_panel_init(&ctx->panel); 468 + ctx->panel.dev = dev; 469 + ctx->panel.funcs = &s6e63j0x03_funcs; 470 + 471 + ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx, 472 + &s6e63j0x03_bl_ops, NULL); 473 + if (IS_ERR(ctx->bl_dev)) { 474 + dev_err(dev, "failed to register backlight device\n"); 475 + return PTR_ERR(ctx->bl_dev); 476 + } 477 + 478 + ctx->bl_dev->props.max_brightness = MAX_BRIGHTNESS; 479 + ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS; 480 + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; 481 + 482 + ret = drm_panel_add(&ctx->panel); 483 + if (ret < 0) 484 + goto unregister_backlight; 485 + 486 + ret = mipi_dsi_attach(dsi); 487 + if (ret < 0) 488 + goto remove_panel; 489 + 490 + return ret; 491 + 492 + remove_panel: 493 + drm_panel_remove(&ctx->panel); 494 + 495 + unregister_backlight: 496 + backlight_device_unregister(ctx->bl_dev); 497 + 498 + return ret; 499 + } 500 + 501 + static int s6e63j0x03_remove(struct mipi_dsi_device *dsi) 502 + { 503 + struct s6e63j0x03 *ctx = mipi_dsi_get_drvdata(dsi); 504 + 505 + mipi_dsi_detach(dsi); 506 + drm_panel_remove(&ctx->panel); 507 + 508 + backlight_device_unregister(ctx->bl_dev); 509 + 510 + return 0; 511 + } 512 + 513 + static const struct of_device_id s6e63j0x03_of_match[] = { 514 + { .compatible = "samsung,s6e63j0x03" }, 515 + { } 516 + }; 517 + MODULE_DEVICE_TABLE(of, s6e63j0x03_of_match); 518 + 519 + static struct mipi_dsi_driver s6e63j0x03_driver = { 520 + .probe = s6e63j0x03_probe, 521 + .remove = s6e63j0x03_remove, 522 + .driver = { 523 + .name = "panel_samsung_s6e63j0x03", 524 + .of_match_table = s6e63j0x03_of_match, 525 + }, 526 + }; 527 + module_mipi_dsi_driver(s6e63j0x03_driver); 528 + 529 + MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 530 + MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>"); 531 + MODULE_DESCRIPTION("MIPI-DSI based s6e63j0x03 AMOLED LCD Panel Driver"); 532 + MODULE_LICENSE("GPL v2");
+372
drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
··· 1 + /* 2 + * Copyright (C) 2017 NXP Semiconductors. 3 + * Author: Marco Franchi <marco.franchi@nxp.com> 4 + * 5 + * Based on Panel Simple driver by Thierry Reding <treding@nvidia.com> 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License version 9 + * 2 as published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/backlight.h> 13 + #include <linux/module.h> 14 + #include <linux/of.h> 15 + #include <linux/regulator/consumer.h> 16 + 17 + #include <drm/drmP.h> 18 + #include <drm/drm_crtc.h> 19 + #include <drm/drm_panel.h> 20 + 21 + #include <video/display_timing.h> 22 + #include <video/videomode.h> 23 + 24 + struct seiko_panel_desc { 25 + const struct drm_display_mode *modes; 26 + unsigned int num_modes; 27 + const struct display_timing *timings; 28 + unsigned int num_timings; 29 + 30 + unsigned int bpc; 31 + 32 + /** 33 + * @width: width (in millimeters) of the panel's active display area 34 + * @height: height (in millimeters) of the panel's active display area 35 + */ 36 + struct { 37 + unsigned int width; 38 + unsigned int height; 39 + } size; 40 + 41 + u32 bus_format; 42 + u32 bus_flags; 43 + }; 44 + 45 + struct seiko_panel { 46 + struct drm_panel base; 47 + bool prepared; 48 + bool enabled; 49 + const struct seiko_panel_desc *desc; 50 + struct backlight_device *backlight; 51 + struct regulator *dvdd; 52 + struct regulator *avdd; 53 + }; 54 + 55 + static inline struct seiko_panel *to_seiko_panel(struct drm_panel *panel) 56 + { 57 + return container_of(panel, struct seiko_panel, base); 58 + } 59 + 60 + static int seiko_panel_get_fixed_modes(struct seiko_panel *panel) 61 + { 62 + struct drm_connector *connector = panel->base.connector; 63 + struct drm_device *drm = panel->base.drm; 64 + struct drm_display_mode *mode; 65 + unsigned int i, num = 0; 66 + 67 + if (!panel->desc) 68 + return 0; 69 + 70 + for (i = 0; i < panel->desc->num_timings; i++) { 71 + const struct display_timing *dt = &panel->desc->timings[i]; 72 + struct videomode vm; 73 + 74 + videomode_from_timing(dt, &vm); 75 + mode = drm_mode_create(drm); 76 + if (!mode) { 77 + dev_err(drm->dev, "failed to add mode %ux%u\n", 78 + dt->hactive.typ, dt->vactive.typ); 79 + continue; 80 + } 81 + 82 + drm_display_mode_from_videomode(&vm, mode); 83 + 84 + mode->type |= DRM_MODE_TYPE_DRIVER; 85 + 86 + if (panel->desc->num_timings == 1) 87 + mode->type |= DRM_MODE_TYPE_PREFERRED; 88 + 89 + drm_mode_probed_add(connector, mode); 90 + num++; 91 + } 92 + 93 + for (i = 0; i < panel->desc->num_modes; i++) { 94 + const struct drm_display_mode *m = &panel->desc->modes[i]; 95 + 96 + mode = drm_mode_duplicate(drm, m); 97 + if (!mode) { 98 + dev_err(drm->dev, "failed to add mode %ux%u@%u\n", 99 + m->hdisplay, m->vdisplay, m->vrefresh); 100 + continue; 101 + } 102 + 103 + mode->type |= DRM_MODE_TYPE_DRIVER; 104 + 105 + if (panel->desc->num_modes == 1) 106 + mode->type |= DRM_MODE_TYPE_PREFERRED; 107 + 108 + drm_mode_set_name(mode); 109 + 110 + drm_mode_probed_add(connector, mode); 111 + num++; 112 + } 113 + 114 + connector->display_info.bpc = panel->desc->bpc; 115 + connector->display_info.width_mm = panel->desc->size.width; 116 + connector->display_info.height_mm = panel->desc->size.height; 117 + if (panel->desc->bus_format) 118 + drm_display_info_set_bus_formats(&connector->display_info, 119 + &panel->desc->bus_format, 1); 120 + connector->display_info.bus_flags = panel->desc->bus_flags; 121 + 122 + return num; 123 + } 124 + 125 + static int seiko_panel_disable(struct drm_panel *panel) 126 + { 127 + struct seiko_panel *p = to_seiko_panel(panel); 128 + 129 + if (!p->enabled) 130 + return 0; 131 + 132 + if (p->backlight) { 133 + p->backlight->props.power = FB_BLANK_POWERDOWN; 134 + p->backlight->props.state |= BL_CORE_FBBLANK; 135 + backlight_update_status(p->backlight); 136 + } 137 + 138 + p->enabled = false; 139 + 140 + return 0; 141 + } 142 + 143 + static int seiko_panel_unprepare(struct drm_panel *panel) 144 + { 145 + struct seiko_panel *p = to_seiko_panel(panel); 146 + 147 + if (!p->prepared) 148 + return 0; 149 + 150 + regulator_disable(p->avdd); 151 + 152 + /* Add a 100ms delay as per the panel datasheet */ 153 + msleep(100); 154 + 155 + regulator_disable(p->dvdd); 156 + 157 + p->prepared = false; 158 + 159 + return 0; 160 + } 161 + 162 + static int seiko_panel_prepare(struct drm_panel *panel) 163 + { 164 + struct seiko_panel *p = to_seiko_panel(panel); 165 + int err; 166 + 167 + if (p->prepared) 168 + return 0; 169 + 170 + err = regulator_enable(p->dvdd); 171 + if (err < 0) { 172 + dev_err(panel->dev, "failed to enable dvdd: %d\n", err); 173 + return err; 174 + } 175 + 176 + /* Add a 100ms delay as per the panel datasheet */ 177 + msleep(100); 178 + 179 + err = regulator_enable(p->avdd); 180 + if (err < 0) { 181 + dev_err(panel->dev, "failed to enable avdd: %d\n", err); 182 + goto disable_dvdd; 183 + } 184 + 185 + p->prepared = true; 186 + 187 + return 0; 188 + 189 + disable_dvdd: 190 + regulator_disable(p->dvdd); 191 + return err; 192 + } 193 + 194 + static int seiko_panel_enable(struct drm_panel *panel) 195 + { 196 + struct seiko_panel *p = to_seiko_panel(panel); 197 + 198 + if (p->enabled) 199 + return 0; 200 + 201 + if (p->backlight) { 202 + p->backlight->props.state &= ~BL_CORE_FBBLANK; 203 + p->backlight->props.power = FB_BLANK_UNBLANK; 204 + backlight_update_status(p->backlight); 205 + } 206 + 207 + p->enabled = true; 208 + 209 + return 0; 210 + } 211 + 212 + static int seiko_panel_get_modes(struct drm_panel *panel) 213 + { 214 + struct seiko_panel *p = to_seiko_panel(panel); 215 + 216 + /* add hard-coded panel modes */ 217 + return seiko_panel_get_fixed_modes(p); 218 + } 219 + 220 + static int seiko_panel_get_timings(struct drm_panel *panel, 221 + unsigned int num_timings, 222 + struct display_timing *timings) 223 + { 224 + struct seiko_panel *p = to_seiko_panel(panel); 225 + unsigned int i; 226 + 227 + if (p->desc->num_timings < num_timings) 228 + num_timings = p->desc->num_timings; 229 + 230 + if (timings) 231 + for (i = 0; i < num_timings; i++) 232 + timings[i] = p->desc->timings[i]; 233 + 234 + return p->desc->num_timings; 235 + } 236 + 237 + static const struct drm_panel_funcs seiko_panel_funcs = { 238 + .disable = seiko_panel_disable, 239 + .unprepare = seiko_panel_unprepare, 240 + .prepare = seiko_panel_prepare, 241 + .enable = seiko_panel_enable, 242 + .get_modes = seiko_panel_get_modes, 243 + .get_timings = seiko_panel_get_timings, 244 + }; 245 + 246 + static int seiko_panel_probe(struct device *dev, 247 + const struct seiko_panel_desc *desc) 248 + { 249 + struct device_node *backlight; 250 + struct seiko_panel *panel; 251 + int err; 252 + 253 + panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); 254 + if (!panel) 255 + return -ENOMEM; 256 + 257 + panel->enabled = false; 258 + panel->prepared = false; 259 + panel->desc = desc; 260 + 261 + panel->dvdd = devm_regulator_get(dev, "dvdd"); 262 + if (IS_ERR(panel->dvdd)) 263 + return PTR_ERR(panel->dvdd); 264 + 265 + panel->avdd = devm_regulator_get(dev, "avdd"); 266 + if (IS_ERR(panel->avdd)) 267 + return PTR_ERR(panel->avdd); 268 + 269 + backlight = of_parse_phandle(dev->of_node, "backlight", 0); 270 + if (backlight) { 271 + panel->backlight = of_find_backlight_by_node(backlight); 272 + of_node_put(backlight); 273 + 274 + if (!panel->backlight) 275 + return -EPROBE_DEFER; 276 + } 277 + 278 + drm_panel_init(&panel->base); 279 + panel->base.dev = dev; 280 + panel->base.funcs = &seiko_panel_funcs; 281 + 282 + err = drm_panel_add(&panel->base); 283 + if (err < 0) 284 + return err; 285 + 286 + dev_set_drvdata(dev, panel); 287 + 288 + return 0; 289 + } 290 + 291 + static int seiko_panel_remove(struct platform_device *pdev) 292 + { 293 + struct seiko_panel *panel = dev_get_drvdata(&pdev->dev); 294 + 295 + drm_panel_detach(&panel->base); 296 + drm_panel_remove(&panel->base); 297 + 298 + seiko_panel_disable(&panel->base); 299 + 300 + if (panel->backlight) 301 + put_device(&panel->backlight->dev); 302 + 303 + return 0; 304 + } 305 + 306 + static void seiko_panel_shutdown(struct platform_device *pdev) 307 + { 308 + struct seiko_panel *panel = dev_get_drvdata(&pdev->dev); 309 + 310 + seiko_panel_disable(&panel->base); 311 + } 312 + 313 + static const struct display_timing seiko_43wvf1g_timing = { 314 + .pixelclock = { 33500000, 33500000, 33500000 }, 315 + .hactive = { 800, 800, 800 }, 316 + .hfront_porch = { 164, 164, 164 }, 317 + .hback_porch = { 89, 89, 89 }, 318 + .hsync_len = { 10, 10, 10 }, 319 + .vactive = { 480, 480, 480 }, 320 + .vfront_porch = { 10, 10, 10 }, 321 + .vback_porch = { 23, 23, 23 }, 322 + .vsync_len = { 10, 10, 10 }, 323 + .flags = DISPLAY_FLAGS_DE_LOW, 324 + }; 325 + 326 + static const struct seiko_panel_desc seiko_43wvf1g = { 327 + .timings = &seiko_43wvf1g_timing, 328 + .num_timings = 1, 329 + .bpc = 8, 330 + .size = { 331 + .width = 93, 332 + .height = 57, 333 + }, 334 + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 335 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE, 336 + }; 337 + 338 + static const struct of_device_id platform_of_match[] = { 339 + { 340 + .compatible = "sii,43wvf1g", 341 + .data = &seiko_43wvf1g, 342 + }, { 343 + /* sentinel */ 344 + } 345 + }; 346 + MODULE_DEVICE_TABLE(of, platform_of_match); 347 + 348 + static int seiko_panel_platform_probe(struct platform_device *pdev) 349 + { 350 + const struct of_device_id *id; 351 + 352 + id = of_match_node(platform_of_match, pdev->dev.of_node); 353 + if (!id) 354 + return -ENODEV; 355 + 356 + return seiko_panel_probe(&pdev->dev, id->data); 357 + } 358 + 359 + static struct platform_driver seiko_panel_platform_driver = { 360 + .driver = { 361 + .name = "seiko_panel", 362 + .of_match_table = platform_of_match, 363 + }, 364 + .probe = seiko_panel_platform_probe, 365 + .remove = seiko_panel_remove, 366 + .shutdown = seiko_panel_shutdown, 367 + }; 368 + module_platform_driver(seiko_panel_platform_driver); 369 + 370 + MODULE_AUTHOR("Marco Franchi <marco.franchi@nxp.com"); 371 + MODULE_DESCRIPTION("Seiko 43WVF1G panel driver"); 372 + MODULE_LICENSE("GPL v2");
+8 -7
drivers/gpu/drm/panel/panel-simple.c
··· 187 187 if (!p->prepared) 188 188 return 0; 189 189 190 - if (p->enable_gpio) 191 - gpiod_set_value_cansleep(p->enable_gpio, 0); 190 + gpiod_set_value_cansleep(p->enable_gpio, 0); 192 191 193 192 regulator_disable(p->supply); 194 193 ··· 213 214 return err; 214 215 } 215 216 216 - if (p->enable_gpio) 217 - gpiod_set_value_cansleep(p->enable_gpio, 1); 217 + gpiod_set_value_cansleep(p->enable_gpio, 1); 218 218 219 219 if (p->desc->delay.prepare) 220 220 msleep(p->desc->delay.prepare); ··· 313 315 GPIOD_OUT_LOW); 314 316 if (IS_ERR(panel->enable_gpio)) { 315 317 err = PTR_ERR(panel->enable_gpio); 316 - dev_err(dev, "failed to request GPIO: %d\n", err); 318 + if (err != -EPROBE_DEFER) 319 + dev_err(dev, "failed to request GPIO: %d\n", err); 317 320 return err; 318 321 } 319 322 ··· 368 369 drm_panel_remove(&panel->base); 369 370 370 371 panel_simple_disable(&panel->base); 372 + panel_simple_unprepare(&panel->base); 371 373 372 374 if (panel->ddc) 373 375 put_device(&panel->ddc->dev); ··· 384 384 struct panel_simple *panel = dev_get_drvdata(dev); 385 385 386 386 panel_simple_disable(&panel->base); 387 + panel_simple_unprepare(&panel->base); 387 388 } 388 389 389 390 static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = { ··· 1523 1522 .modes = &olimex_lcd_olinuxino_43ts_mode, 1524 1523 .num_modes = 1, 1525 1524 .size = { 1526 - .width = 105, 1527 - .height = 67, 1525 + .width = 95, 1526 + .height = 54, 1528 1527 }, 1529 1528 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1530 1529 };
+2 -1
drivers/gpu/drm/pl111/Kconfig
··· 6 6 select DRM_KMS_HELPER 7 7 select DRM_KMS_CMA_HELPER 8 8 select DRM_GEM_CMA_HELPER 9 - select DRM_PANEL 9 + select DRM_BRIDGE 10 + select DRM_PANEL_BRIDGE 10 11 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE 11 12 help 12 13 Choose this option for DRM support for the PL111 CLCD controller.
+2 -2
drivers/gpu/drm/pl111/Makefile
··· 1 - pl111_drm-y += pl111_connector.o \ 2 - pl111_display.o \ 1 + pl111_drm-y += pl111_display.o \ 2 + pl111_versatile.o \ 3 3 pl111_drv.o 4 4 5 5 pl111_drm-$(CONFIG_DEBUG_FS) += pl111_debugfs.o
-126
drivers/gpu/drm/pl111/pl111_connector.c
··· 1 - /* 2 - * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved. 3 - * 4 - * Parts of this file were based on sources as follows: 5 - * 6 - * Copyright (c) 2006-2008 Intel Corporation 7 - * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 8 - * Copyright (C) 2011 Texas Instruments 9 - * 10 - * This program is free software and is provided to you under the terms of the 11 - * GNU General Public License version 2 as published by the Free Software 12 - * Foundation, and any use by you of this program is subject to the terms of 13 - * such GNU licence. 14 - * 15 - */ 16 - 17 - /** 18 - * pl111_drm_connector.c 19 - * Implementation of the connector functions for PL111 DRM 20 - */ 21 - #include <linux/amba/clcd-regs.h> 22 - #include <linux/version.h> 23 - #include <linux/shmem_fs.h> 24 - #include <linux/dma-buf.h> 25 - 26 - #include <drm/drmP.h> 27 - #include <drm/drm_atomic_helper.h> 28 - #include <drm/drm_crtc_helper.h> 29 - #include <drm/drm_of.h> 30 - #include <drm/drm_panel.h> 31 - 32 - #include "pl111_drm.h" 33 - 34 - static void pl111_connector_destroy(struct drm_connector *connector) 35 - { 36 - struct pl111_drm_connector *pl111_connector = 37 - to_pl111_connector(connector); 38 - 39 - if (pl111_connector->panel) 40 - drm_panel_detach(pl111_connector->panel); 41 - 42 - drm_connector_unregister(connector); 43 - drm_connector_cleanup(connector); 44 - } 45 - 46 - static enum drm_connector_status pl111_connector_detect(struct drm_connector 47 - *connector, bool force) 48 - { 49 - struct pl111_drm_connector *pl111_connector = 50 - to_pl111_connector(connector); 51 - 52 - return (pl111_connector->panel ? 53 - connector_status_connected : 54 - connector_status_disconnected); 55 - } 56 - 57 - static int pl111_connector_helper_get_modes(struct drm_connector *connector) 58 - { 59 - struct pl111_drm_connector *pl111_connector = 60 - to_pl111_connector(connector); 61 - 62 - if (!pl111_connector->panel) 63 - return 0; 64 - 65 - return drm_panel_get_modes(pl111_connector->panel); 66 - } 67 - 68 - const struct drm_connector_funcs connector_funcs = { 69 - .fill_modes = drm_helper_probe_single_connector_modes, 70 - .destroy = pl111_connector_destroy, 71 - .detect = pl111_connector_detect, 72 - .reset = drm_atomic_helper_connector_reset, 73 - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 74 - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 75 - }; 76 - 77 - const struct drm_connector_helper_funcs connector_helper_funcs = { 78 - .get_modes = pl111_connector_helper_get_modes, 79 - }; 80 - 81 - /* Walks the OF graph to find the panel node and then asks DRM to look 82 - * up the panel. 83 - */ 84 - static struct drm_panel *pl111_get_panel(struct device *dev) 85 - { 86 - struct device_node *endpoint, *panel_node; 87 - struct device_node *np = dev->of_node; 88 - struct drm_panel *panel; 89 - 90 - endpoint = of_graph_get_next_endpoint(np, NULL); 91 - if (!endpoint) { 92 - dev_err(dev, "no endpoint to fetch panel\n"); 93 - return NULL; 94 - } 95 - 96 - /* don't proceed if we have an endpoint but no panel_node tied to it */ 97 - panel_node = of_graph_get_remote_port_parent(endpoint); 98 - of_node_put(endpoint); 99 - if (!panel_node) { 100 - dev_err(dev, "no valid panel node\n"); 101 - return NULL; 102 - } 103 - 104 - panel = of_drm_find_panel(panel_node); 105 - of_node_put(panel_node); 106 - 107 - return panel; 108 - } 109 - 110 - int pl111_connector_init(struct drm_device *dev) 111 - { 112 - struct pl111_drm_dev_private *priv = dev->dev_private; 113 - struct pl111_drm_connector *pl111_connector = &priv->connector; 114 - struct drm_connector *connector = &pl111_connector->connector; 115 - 116 - drm_connector_init(dev, connector, &connector_funcs, 117 - DRM_MODE_CONNECTOR_DPI); 118 - drm_connector_helper_add(connector, &connector_helper_funcs); 119 - 120 - pl111_connector->panel = pl111_get_panel(dev->dev); 121 - if (pl111_connector->panel) 122 - drm_panel_attach(pl111_connector->panel, connector); 123 - 124 - return 0; 125 - } 126 -
+6
drivers/gpu/drm/pl111/pl111_debugfs.c
··· 22 22 REGDEF(CLCD_TIM2), 23 23 REGDEF(CLCD_TIM3), 24 24 REGDEF(CLCD_UBAS), 25 + REGDEF(CLCD_LBAS), 25 26 REGDEF(CLCD_PL111_CNTL), 26 27 REGDEF(CLCD_PL111_IENB), 28 + REGDEF(CLCD_PL111_RIS), 29 + REGDEF(CLCD_PL111_MIS), 30 + REGDEF(CLCD_PL111_ICR), 31 + REGDEF(CLCD_PL111_UCUR), 32 + REGDEF(CLCD_PL111_LCUR), 27 33 }; 28 34 29 35 int pl111_debugfs_regs(struct seq_file *m, void *unused)
+40 -39
drivers/gpu/drm/pl111/pl111_display.c
··· 21 21 #include <linux/of_graph.h> 22 22 23 23 #include <drm/drmP.h> 24 - #include <drm/drm_panel.h> 25 24 #include <drm/drm_gem_cma_helper.h> 26 25 #include <drm/drm_gem_framebuffer_helper.h> 27 26 #include <drm/drm_fb_cma_helper.h> ··· 93 94 struct pl111_drm_dev_private *priv = drm->dev_private; 94 95 const struct drm_display_mode *mode = &cstate->mode; 95 96 struct drm_framebuffer *fb = plane->state->fb; 96 - struct drm_connector *connector = &priv->connector.connector; 97 + struct drm_connector *connector = priv->connector; 97 98 u32 cntl; 98 99 u32 ppl, hsw, hfp, hbp; 99 100 u32 lpp, vsw, vfp, vbp; ··· 155 156 156 157 writel(0, priv->regs + CLCD_TIM3); 157 158 158 - drm_panel_prepare(priv->connector.panel); 159 - 160 - /* Enable and Power Up */ 161 - cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDPWR | CNTL_LCDVCOMP(1); 159 + /* Hard-code TFT panel */ 160 + cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); 162 161 163 162 /* Note that the the hardware's format reader takes 'r' from 164 163 * the low bit, while DRM formats list channels from high bit ··· 199 202 break; 200 203 } 201 204 202 - writel(cntl, priv->regs + CLCD_PL111_CNTL); 205 + /* Power sequence: first enable and chill */ 206 + writel(cntl, priv->regs + priv->ctrl); 203 207 204 - drm_panel_enable(priv->connector.panel); 208 + /* 209 + * We expect this delay to stabilize the contrast 210 + * voltage Vee as stipulated by the manual 211 + */ 212 + msleep(20); 213 + 214 + if (priv->variant_display_enable) 215 + priv->variant_display_enable(drm, fb->format->format); 216 + 217 + /* Power Up */ 218 + cntl |= CNTL_LCDPWR; 219 + writel(cntl, priv->regs + priv->ctrl); 205 220 206 221 drm_crtc_vblank_on(crtc); 207 222 } ··· 223 214 struct drm_crtc *crtc = &pipe->crtc; 224 215 struct drm_device *drm = crtc->dev; 225 216 struct pl111_drm_dev_private *priv = drm->dev_private; 217 + u32 cntl; 226 218 227 219 drm_crtc_vblank_off(crtc); 228 220 229 - drm_panel_disable(priv->connector.panel); 221 + /* Power Down */ 222 + cntl = readl(priv->regs + priv->ctrl); 223 + if (cntl & CNTL_LCDPWR) { 224 + cntl &= ~CNTL_LCDPWR; 225 + writel(cntl, priv->regs + priv->ctrl); 226 + } 230 227 231 - /* Disable and Power Down */ 232 - writel(0, priv->regs + CLCD_PL111_CNTL); 228 + /* 229 + * We expect this delay to stabilize the contrast voltage Vee as 230 + * stipulated by the manual 231 + */ 232 + msleep(20); 233 233 234 - drm_panel_unprepare(priv->connector.panel); 234 + if (priv->variant_display_disable) 235 + priv->variant_display_disable(drm); 236 + 237 + /* Disable */ 238 + writel(0, priv->regs + priv->ctrl); 235 239 236 240 clk_disable_unprepare(priv->clk); 237 241 } ··· 282 260 { 283 261 struct pl111_drm_dev_private *priv = drm->dev_private; 284 262 285 - writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + CLCD_PL111_IENB); 263 + writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb); 286 264 287 265 return 0; 288 266 } ··· 291 269 { 292 270 struct pl111_drm_dev_private *priv = drm->dev_private; 293 271 294 - writel(0, priv->regs + CLCD_PL111_IENB); 272 + writel(0, priv->regs + priv->ienb); 295 273 } 296 274 297 275 static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe, ··· 435 413 struct device_node *endpoint; 436 414 u32 tft_r0b0g0[3]; 437 415 int ret; 438 - static const u32 formats[] = { 439 - DRM_FORMAT_ABGR8888, 440 - DRM_FORMAT_XBGR8888, 441 - DRM_FORMAT_ARGB8888, 442 - DRM_FORMAT_XRGB8888, 443 - DRM_FORMAT_BGR565, 444 - DRM_FORMAT_RGB565, 445 - DRM_FORMAT_ABGR1555, 446 - DRM_FORMAT_XBGR1555, 447 - DRM_FORMAT_ARGB1555, 448 - DRM_FORMAT_XRGB1555, 449 - DRM_FORMAT_ABGR4444, 450 - DRM_FORMAT_XBGR4444, 451 - DRM_FORMAT_ARGB4444, 452 - DRM_FORMAT_XRGB4444, 453 - }; 454 416 455 417 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 456 418 if (!endpoint) ··· 450 444 } 451 445 of_node_put(endpoint); 452 446 453 - if (tft_r0b0g0[0] != 0 || 454 - tft_r0b0g0[1] != 8 || 455 - tft_r0b0g0[2] != 16) { 456 - dev_err(dev, "arm,pl11x,tft-r0g0b0-pads != [0,8,16] not yet supported\n"); 457 - return -EINVAL; 458 - } 459 - 460 447 ret = pl111_init_clock_divider(drm); 461 448 if (ret) 462 449 return ret; 463 450 464 451 ret = drm_simple_display_pipe_init(drm, &priv->pipe, 465 452 &pl111_display_funcs, 466 - formats, ARRAY_SIZE(formats), 467 - NULL, &priv->connector.connector); 453 + priv->variant->formats, 454 + priv->variant->nformats, 455 + NULL, 456 + priv->connector); 468 457 if (ret) 469 458 return ret; 470 459
+25 -12
drivers/gpu/drm/pl111/pl111_drm.h
··· 21 21 22 22 #include <drm/drm_gem.h> 23 23 #include <drm/drm_simple_kms_helper.h> 24 + #include <drm/drm_connector.h> 25 + #include <drm/drm_encoder.h> 26 + #include <drm/drm_panel.h> 27 + #include <drm/drm_bridge.h> 24 28 #include <linux/clk-provider.h> 29 + #include <linux/interrupt.h> 25 30 26 31 #define CLCD_IRQ_NEXTBASE_UPDATE BIT(2) 27 32 28 33 struct drm_minor; 29 34 30 - struct pl111_drm_connector { 31 - struct drm_connector connector; 32 - struct drm_panel *panel; 35 + /** 36 + * struct pl111_variant_data - encodes IP differences 37 + * @name: the name of this variant 38 + * @is_pl110: this is the early PL110 variant 39 + * @formats: array of supported pixel formats on this variant 40 + * @nformats: the length of the array of supported pixel formats 41 + */ 42 + struct pl111_variant_data { 43 + const char *name; 44 + bool is_pl110; 45 + const u32 *formats; 46 + unsigned int nformats; 33 47 }; 34 48 35 49 struct pl111_drm_dev_private { 36 50 struct drm_device *drm; 37 51 38 - struct pl111_drm_connector connector; 52 + struct drm_connector *connector; 53 + struct drm_panel *panel; 54 + struct drm_bridge *bridge; 39 55 struct drm_simple_display_pipe pipe; 40 56 struct drm_fbdev_cma *fbdev; 41 57 42 58 void *regs; 59 + u32 ienb; 60 + u32 ctrl; 43 61 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */ 44 62 struct clk *clk; 45 63 /* pl111's internal clock divider. */ ··· 66 48 * subsystem and pl111_display_enable(). 67 49 */ 68 50 spinlock_t tim2_lock; 51 + const struct pl111_variant_data *variant; 52 + void (*variant_display_enable) (struct drm_device *drm, u32 format); 53 + void (*variant_display_disable) (struct drm_device *drm); 69 54 }; 70 - 71 - #define to_pl111_connector(x) \ 72 - container_of(x, struct pl111_drm_connector, connector) 73 55 74 56 int pl111_display_init(struct drm_device *dev); 75 57 int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc); 76 58 void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc); 77 59 irqreturn_t pl111_irq(int irq, void *data); 78 - int pl111_connector_init(struct drm_device *dev); 79 - int pl111_encoder_init(struct drm_device *dev); 80 - int pl111_dumb_create(struct drm_file *file_priv, 81 - struct drm_device *dev, 82 - struct drm_mode_create_dumb *args); 83 60 int pl111_debugfs_init(struct drm_minor *minor); 84 61 85 62 #endif /* _PL111_DRM_H_ */
+125 -24
drivers/gpu/drm/pl111/pl111_drv.c
··· 41 41 * - Fix race between setting plane base address and getting IRQ for 42 42 * vsync firing the pageflip completion. 43 43 * 44 - * - Expose the correct set of formats we can support based on the 45 - * "arm,pl11x,tft-r0g0b0-pads" DT property. 46 - * 47 44 * - Use the "max-memory-bandwidth" DT property to filter the 48 45 * supported formats. 49 46 * ··· 65 68 #include <drm/drm_gem_cma_helper.h> 66 69 #include <drm/drm_gem_framebuffer_helper.h> 67 70 #include <drm/drm_fb_cma_helper.h> 71 + #include <drm/drm_of.h> 72 + #include <drm/drm_bridge.h> 73 + #include <drm/drm_panel.h> 68 74 69 75 #include "pl111_drm.h" 76 + #include "pl111_versatile.h" 70 77 71 78 #define DRIVER_DESC "DRM module for PL111" 72 79 ··· 84 83 { 85 84 struct drm_mode_config *mode_config; 86 85 struct pl111_drm_dev_private *priv = dev->dev_private; 86 + struct drm_panel *panel; 87 + struct drm_bridge *bridge; 87 88 int ret = 0; 88 89 89 90 drm_mode_config_init(dev); ··· 96 93 mode_config->min_height = 1; 97 94 mode_config->max_height = 768; 98 95 99 - ret = pl111_connector_init(dev); 100 - if (ret) { 101 - dev_err(dev->dev, "Failed to create pl111_drm_connector\n"); 102 - goto out_config; 103 - } 104 - 105 - /* Don't actually attach if we didn't find a drm_panel 106 - * attached to us. This will allow a kernel to include both 107 - * the fbdev pl111 driver and this one, and choose between 108 - * them based on which subsystem has support for the panel. 109 - */ 110 - if (!priv->connector.panel) { 111 - dev_info(dev->dev, 112 - "Disabling due to lack of DRM panel device.\n"); 113 - ret = -ENODEV; 114 - goto out_config; 96 + ret = drm_of_find_panel_or_bridge(dev->dev->of_node, 97 + 0, 0, &panel, &bridge); 98 + if (ret && ret != -ENODEV) 99 + return ret; 100 + if (panel) { 101 + bridge = drm_panel_bridge_add(panel, 102 + DRM_MODE_CONNECTOR_Unknown); 103 + if (IS_ERR(bridge)) { 104 + ret = PTR_ERR(bridge); 105 + goto out_config; 106 + } 107 + /* 108 + * TODO: when we are using a different bridge than a panel 109 + * (such as a dumb VGA connector) we need to devise a different 110 + * method to get the connector out of the bridge. 111 + */ 115 112 } 116 113 117 114 ret = pl111_display_init(dev); 118 115 if (ret != 0) { 119 116 dev_err(dev->dev, "Failed to init display\n"); 120 - goto out_config; 117 + goto out_bridge; 121 118 } 119 + 120 + ret = drm_simple_display_pipe_attach_bridge(&priv->pipe, 121 + bridge); 122 + if (ret) 123 + return ret; 124 + 125 + priv->bridge = bridge; 126 + priv->panel = panel; 127 + priv->connector = panel->connector; 122 128 123 129 ret = drm_vblank_init(dev, 1); 124 130 if (ret != 0) { 125 131 dev_err(dev->dev, "Failed to init vblank\n"); 126 - goto out_config; 132 + goto out_bridge; 127 133 } 128 134 129 135 drm_mode_config_reset(dev); ··· 144 132 145 133 goto finish; 146 134 135 + out_bridge: 136 + if (panel) 137 + drm_panel_bridge_remove(bridge); 147 138 out_config: 148 139 drm_mode_config_cleanup(dev); 149 140 finish: ··· 198 183 { 199 184 struct device *dev = &amba_dev->dev; 200 185 struct pl111_drm_dev_private *priv; 186 + struct pl111_variant_data *variant = id->data; 201 187 struct drm_device *drm; 202 188 int ret; 203 189 ··· 212 196 amba_set_drvdata(amba_dev, drm); 213 197 priv->drm = drm; 214 198 drm->dev_private = priv; 199 + priv->variant = variant; 200 + 201 + /* 202 + * The PL110 and PL111 variants have two registers 203 + * swapped: interrupt enable and control. For this reason 204 + * we use offsets that we can change per variant. 205 + */ 206 + if (variant->is_pl110) { 207 + /* 208 + * The ARM Versatile boards are even more special: 209 + * their PrimeCell ID say they are PL110 but the 210 + * control and interrupt enable registers are anyway 211 + * swapped to the PL111 order so they are not following 212 + * the PL110 datasheet. 213 + */ 214 + if (of_machine_is_compatible("arm,versatile-ab") || 215 + of_machine_is_compatible("arm,versatile-pb")) { 216 + priv->ienb = CLCD_PL111_IENB; 217 + priv->ctrl = CLCD_PL111_CNTL; 218 + } else { 219 + priv->ienb = CLCD_PL110_IENB; 220 + priv->ctrl = CLCD_PL110_CNTL; 221 + } 222 + } else { 223 + priv->ienb = CLCD_PL111_IENB; 224 + priv->ctrl = CLCD_PL111_CNTL; 225 + } 215 226 216 227 priv->regs = devm_ioremap_resource(dev, &amba_dev->res); 217 228 if (IS_ERR(priv->regs)) { ··· 247 204 } 248 205 249 206 /* turn off interrupts before requesting the irq */ 250 - writel(0, priv->regs + CLCD_PL111_IENB); 207 + writel(0, priv->regs + priv->ienb); 251 208 252 209 ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0, 253 - "pl111", priv); 210 + variant->name, priv); 254 211 if (ret != 0) { 255 212 dev_err(dev, "%s failed irq %d\n", __func__, ret); 256 213 return ret; 257 214 } 215 + 216 + ret = pl111_versatile_init(dev, priv); 217 + if (ret) 218 + goto dev_unref; 258 219 259 220 ret = pl111_modeset_init(drm); 260 221 if (ret != 0) ··· 283 236 drm_dev_unregister(drm); 284 237 if (priv->fbdev) 285 238 drm_fbdev_cma_fini(priv->fbdev); 239 + if (priv->panel) 240 + drm_panel_bridge_remove(priv->bridge); 286 241 drm_mode_config_cleanup(drm); 287 242 drm_dev_unref(drm); 288 243 289 244 return 0; 290 245 } 291 246 292 - static struct amba_id pl111_id_table[] = { 247 + /* 248 + * This variant exist in early versions like the ARM Integrator 249 + * and this version lacks the 565 and 444 pixel formats. 250 + */ 251 + static const u32 pl110_pixel_formats[] = { 252 + DRM_FORMAT_ABGR8888, 253 + DRM_FORMAT_XBGR8888, 254 + DRM_FORMAT_ARGB8888, 255 + DRM_FORMAT_XRGB8888, 256 + DRM_FORMAT_ABGR1555, 257 + DRM_FORMAT_XBGR1555, 258 + DRM_FORMAT_ARGB1555, 259 + DRM_FORMAT_XRGB1555, 260 + }; 261 + 262 + static const struct pl111_variant_data pl110_variant = { 263 + .name = "PL110", 264 + .is_pl110 = true, 265 + .formats = pl110_pixel_formats, 266 + .nformats = ARRAY_SIZE(pl110_pixel_formats), 267 + }; 268 + 269 + /* RealView, Versatile Express etc use this modern variant */ 270 + static const u32 pl111_pixel_formats[] = { 271 + DRM_FORMAT_ABGR8888, 272 + DRM_FORMAT_XBGR8888, 273 + DRM_FORMAT_ARGB8888, 274 + DRM_FORMAT_XRGB8888, 275 + DRM_FORMAT_BGR565, 276 + DRM_FORMAT_RGB565, 277 + DRM_FORMAT_ABGR1555, 278 + DRM_FORMAT_XBGR1555, 279 + DRM_FORMAT_ARGB1555, 280 + DRM_FORMAT_XRGB1555, 281 + DRM_FORMAT_ABGR4444, 282 + DRM_FORMAT_XBGR4444, 283 + DRM_FORMAT_ARGB4444, 284 + DRM_FORMAT_XRGB4444, 285 + }; 286 + 287 + static const struct pl111_variant_data pl111_variant = { 288 + .name = "PL111", 289 + .formats = pl111_pixel_formats, 290 + .nformats = ARRAY_SIZE(pl111_pixel_formats), 291 + }; 292 + 293 + static const struct amba_id pl111_id_table[] = { 294 + { 295 + .id = 0x00041110, 296 + .mask = 0x000fffff, 297 + .data = (void*)&pl110_variant, 298 + }, 293 299 { 294 300 .id = 0x00041111, 295 301 .mask = 0x000fffff, 302 + .data = (void*)&pl111_variant, 296 303 }, 297 304 {0, 0}, 298 305 };
+270
drivers/gpu/drm/pl111/pl111_versatile.c
··· 1 + #include <linux/device.h> 2 + #include <linux/of.h> 3 + #include <linux/regmap.h> 4 + #include <linux/mfd/syscon.h> 5 + #include <linux/bitops.h> 6 + #include <linux/module.h> 7 + #include <drm/drmP.h> 8 + #include "pl111_versatile.h" 9 + #include "pl111_drm.h" 10 + 11 + static struct regmap *versatile_syscon_map; 12 + 13 + /* 14 + * We detect the different syscon types from the compatible strings. 15 + */ 16 + enum versatile_clcd { 17 + INTEGRATOR_CLCD_CM, 18 + VERSATILE_CLCD, 19 + REALVIEW_CLCD_EB, 20 + REALVIEW_CLCD_PB1176, 21 + REALVIEW_CLCD_PB11MP, 22 + REALVIEW_CLCD_PBA8, 23 + REALVIEW_CLCD_PBX, 24 + }; 25 + 26 + static const struct of_device_id versatile_clcd_of_match[] = { 27 + { 28 + .compatible = "arm,core-module-integrator", 29 + .data = (void *)INTEGRATOR_CLCD_CM, 30 + }, 31 + { 32 + .compatible = "arm,versatile-sysreg", 33 + .data = (void *)VERSATILE_CLCD, 34 + }, 35 + { 36 + .compatible = "arm,realview-eb-syscon", 37 + .data = (void *)REALVIEW_CLCD_EB, 38 + }, 39 + { 40 + .compatible = "arm,realview-pb1176-syscon", 41 + .data = (void *)REALVIEW_CLCD_PB1176, 42 + }, 43 + { 44 + .compatible = "arm,realview-pb11mp-syscon", 45 + .data = (void *)REALVIEW_CLCD_PB11MP, 46 + }, 47 + { 48 + .compatible = "arm,realview-pba8-syscon", 49 + .data = (void *)REALVIEW_CLCD_PBA8, 50 + }, 51 + { 52 + .compatible = "arm,realview-pbx-syscon", 53 + .data = (void *)REALVIEW_CLCD_PBX, 54 + }, 55 + {}, 56 + }; 57 + 58 + /* 59 + * Core module CLCD control on the Integrator/CP, bits 60 + * 8 thru 19 of the CM_CONTROL register controls a bunch 61 + * of CLCD settings. 62 + */ 63 + #define INTEGRATOR_HDR_CTRL_OFFSET 0x0C 64 + #define INTEGRATOR_CLCD_LCDBIASEN BIT(8) 65 + #define INTEGRATOR_CLCD_LCDBIASUP BIT(9) 66 + #define INTEGRATOR_CLCD_LCDBIASDN BIT(10) 67 + /* Bits 11,12,13 controls the LCD type */ 68 + #define INTEGRATOR_CLCD_LCDMUX_MASK (BIT(11)|BIT(12)|BIT(13)) 69 + #define INTEGRATOR_CLCD_LCDMUX_LCD24 BIT(11) 70 + #define INTEGRATOR_CLCD_LCDMUX_VGA565 BIT(12) 71 + #define INTEGRATOR_CLCD_LCDMUX_SHARP (BIT(11)|BIT(12)) 72 + #define INTEGRATOR_CLCD_LCDMUX_VGA555 BIT(13) 73 + #define INTEGRATOR_CLCD_LCDMUX_VGA24 (BIT(11)|BIT(12)|BIT(13)) 74 + #define INTEGRATOR_CLCD_LCD0_EN BIT(14) 75 + #define INTEGRATOR_CLCD_LCD1_EN BIT(15) 76 + /* R/L flip on Sharp */ 77 + #define INTEGRATOR_CLCD_LCD_STATIC1 BIT(16) 78 + /* U/D flip on Sharp */ 79 + #define INTEGRATOR_CLCD_LCD_STATIC2 BIT(17) 80 + /* No connection on Sharp */ 81 + #define INTEGRATOR_CLCD_LCD_STATIC BIT(18) 82 + /* 0 = 24bit VGA, 1 = 18bit VGA */ 83 + #define INTEGRATOR_CLCD_LCD_N24BITEN BIT(19) 84 + 85 + #define INTEGRATOR_CLCD_MASK (INTEGRATOR_CLCD_LCDBIASEN | \ 86 + INTEGRATOR_CLCD_LCDBIASUP | \ 87 + INTEGRATOR_CLCD_LCDBIASDN | \ 88 + INTEGRATOR_CLCD_LCDMUX_MASK | \ 89 + INTEGRATOR_CLCD_LCD0_EN | \ 90 + INTEGRATOR_CLCD_LCD1_EN | \ 91 + INTEGRATOR_CLCD_LCD_STATIC1 | \ 92 + INTEGRATOR_CLCD_LCD_STATIC2 | \ 93 + INTEGRATOR_CLCD_LCD_STATIC | \ 94 + INTEGRATOR_CLCD_LCD_N24BITEN) 95 + 96 + static void pl111_integrator_enable(struct drm_device *drm, u32 format) 97 + { 98 + u32 val; 99 + 100 + dev_info(drm->dev, "enable Integrator CLCD connectors\n"); 101 + 102 + /* FIXME: really needed? */ 103 + val = INTEGRATOR_CLCD_LCD_STATIC1 | INTEGRATOR_CLCD_LCD_STATIC2 | 104 + INTEGRATOR_CLCD_LCD0_EN | INTEGRATOR_CLCD_LCD1_EN; 105 + 106 + switch (format) { 107 + case DRM_FORMAT_XBGR8888: 108 + case DRM_FORMAT_XRGB8888: 109 + break; 110 + case DRM_FORMAT_BGR565: 111 + case DRM_FORMAT_RGB565: 112 + /* truecolor RGB565 */ 113 + val |= INTEGRATOR_CLCD_LCDMUX_VGA565; 114 + break; 115 + case DRM_FORMAT_XBGR1555: 116 + case DRM_FORMAT_XRGB1555: 117 + /* Pseudocolor, RGB555, BGR555 */ 118 + val |= INTEGRATOR_CLCD_LCDMUX_VGA555; 119 + break; 120 + default: 121 + dev_err(drm->dev, "unhandled format on Integrator 0x%08x\n", 122 + format); 123 + break; 124 + } 125 + 126 + regmap_update_bits(versatile_syscon_map, 127 + INTEGRATOR_HDR_CTRL_OFFSET, 128 + INTEGRATOR_CLCD_MASK, 129 + val); 130 + } 131 + 132 + /* 133 + * This configuration register in the Versatile and RealView 134 + * family is uniformly present but appears more and more 135 + * unutilized starting with the RealView series. 136 + */ 137 + #define SYS_CLCD 0x50 138 + #define SYS_CLCD_MODE_MASK (BIT(0)|BIT(1)) 139 + #define SYS_CLCD_MODE_888 0 140 + #define SYS_CLCD_MODE_5551 BIT(0) 141 + #define SYS_CLCD_MODE_565_R_LSB BIT(1) 142 + #define SYS_CLCD_MODE_565_B_LSB (BIT(0)|BIT(1)) 143 + #define SYS_CLCD_CONNECTOR_MASK (BIT(2)|BIT(3)|BIT(4)|BIT(5)) 144 + #define SYS_CLCD_NLCDIOON BIT(2) 145 + #define SYS_CLCD_VDDPOSSWITCH BIT(3) 146 + #define SYS_CLCD_PWR3V5SWITCH BIT(4) 147 + #define SYS_CLCD_VDDNEGSWITCH BIT(5) 148 + 149 + static void pl111_versatile_disable(struct drm_device *drm) 150 + { 151 + dev_info(drm->dev, "disable Versatile CLCD connectors\n"); 152 + regmap_update_bits(versatile_syscon_map, 153 + SYS_CLCD, 154 + SYS_CLCD_CONNECTOR_MASK, 155 + 0); 156 + } 157 + 158 + static void pl111_versatile_enable(struct drm_device *drm, u32 format) 159 + { 160 + u32 val = 0; 161 + 162 + dev_info(drm->dev, "enable Versatile CLCD connectors\n"); 163 + 164 + switch (format) { 165 + case DRM_FORMAT_ABGR8888: 166 + case DRM_FORMAT_XBGR8888: 167 + case DRM_FORMAT_ARGB8888: 168 + case DRM_FORMAT_XRGB8888: 169 + val |= SYS_CLCD_MODE_888; 170 + break; 171 + case DRM_FORMAT_BGR565: 172 + val |= SYS_CLCD_MODE_565_R_LSB; 173 + break; 174 + case DRM_FORMAT_RGB565: 175 + val |= SYS_CLCD_MODE_565_B_LSB; 176 + break; 177 + case DRM_FORMAT_ABGR1555: 178 + case DRM_FORMAT_XBGR1555: 179 + case DRM_FORMAT_ARGB1555: 180 + case DRM_FORMAT_XRGB1555: 181 + val |= SYS_CLCD_MODE_5551; 182 + break; 183 + default: 184 + dev_err(drm->dev, "unhandled format on Versatile 0x%08x\n", 185 + format); 186 + break; 187 + } 188 + 189 + /* Set up the MUX */ 190 + regmap_update_bits(versatile_syscon_map, 191 + SYS_CLCD, 192 + SYS_CLCD_MODE_MASK, 193 + val); 194 + 195 + /* Then enable the display */ 196 + regmap_update_bits(versatile_syscon_map, 197 + SYS_CLCD, 198 + SYS_CLCD_CONNECTOR_MASK, 199 + SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH); 200 + } 201 + 202 + static void pl111_realview_clcd_disable(struct drm_device *drm) 203 + { 204 + dev_info(drm->dev, "disable RealView CLCD connectors\n"); 205 + regmap_update_bits(versatile_syscon_map, 206 + SYS_CLCD, 207 + SYS_CLCD_CONNECTOR_MASK, 208 + 0); 209 + } 210 + 211 + static void pl111_realview_clcd_enable(struct drm_device *drm, u32 format) 212 + { 213 + dev_info(drm->dev, "enable RealView CLCD connectors\n"); 214 + regmap_update_bits(versatile_syscon_map, 215 + SYS_CLCD, 216 + SYS_CLCD_CONNECTOR_MASK, 217 + SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH); 218 + } 219 + 220 + int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) 221 + { 222 + const struct of_device_id *clcd_id; 223 + enum versatile_clcd versatile_clcd_type; 224 + struct device_node *np; 225 + struct regmap *map; 226 + 227 + np = of_find_matching_node_and_match(NULL, versatile_clcd_of_match, 228 + &clcd_id); 229 + if (!np) { 230 + /* Non-ARM reference designs, just bail out */ 231 + return 0; 232 + } 233 + versatile_clcd_type = (enum versatile_clcd)clcd_id->data; 234 + 235 + map = syscon_node_to_regmap(np); 236 + if (IS_ERR(map)) { 237 + dev_err(dev, "no Versatile syscon regmap\n"); 238 + return PTR_ERR(map); 239 + } 240 + 241 + switch (versatile_clcd_type) { 242 + case INTEGRATOR_CLCD_CM: 243 + versatile_syscon_map = map; 244 + priv->variant_display_enable = pl111_integrator_enable; 245 + dev_info(dev, "set up callbacks for Integrator PL110\n"); 246 + break; 247 + case VERSATILE_CLCD: 248 + versatile_syscon_map = map; 249 + priv->variant_display_enable = pl111_versatile_enable; 250 + priv->variant_display_disable = pl111_versatile_disable; 251 + dev_info(dev, "set up callbacks for Versatile PL110+\n"); 252 + break; 253 + case REALVIEW_CLCD_EB: 254 + case REALVIEW_CLCD_PB1176: 255 + case REALVIEW_CLCD_PB11MP: 256 + case REALVIEW_CLCD_PBA8: 257 + case REALVIEW_CLCD_PBX: 258 + versatile_syscon_map = map; 259 + priv->variant_display_enable = pl111_realview_clcd_enable; 260 + priv->variant_display_disable = pl111_realview_clcd_disable; 261 + dev_info(dev, "set up callbacks for RealView PL111\n"); 262 + break; 263 + default: 264 + dev_info(dev, "unknown Versatile system controller\n"); 265 + break; 266 + } 267 + 268 + return 0; 269 + } 270 + EXPORT_SYMBOL_GPL(pl111_versatile_init);
+9
drivers/gpu/drm/pl111/pl111_versatile.h
··· 1 + #include <linux/device.h> 2 + #include "pl111_drm.h" 3 + 4 + #ifndef PL111_VERSATILE_H 5 + #define PL111_VERSATILE_H 6 + 7 + int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv); 8 + 9 + #endif
+8
drivers/gpu/drm/rockchip/Kconfig
··· 57 57 for the Innosilicon HDMI driver. If you want to enable 58 58 HDMI on RK3036 based SoC, you should select this option. 59 59 60 + config ROCKCHIP_LVDS 61 + bool "Rockchip LVDS support" 62 + depends on DRM_ROCKCHIP 63 + help 64 + Choose this option to enable support for Rockchip LVDS controllers. 65 + Rockchip rk3288 SoC has LVDS TX Controller can be used, and it 66 + support LVDS, rgb, dual LVDS output mode. say Y to enable its 67 + driver. 60 68 endif
+1
drivers/gpu/drm/rockchip/Makefile
··· 12 12 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o 13 13 rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o 14 14 rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o 15 + rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o 15 16 16 17 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
+13 -13
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
··· 88 88 if (!analogix_dp_psr_supported(dp->dev)) 89 89 return; 90 90 91 - dev_dbg(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 91 + DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 92 92 93 93 spin_lock_irqsave(&dp->psr_lock, flags); 94 94 if (enabled) ··· 110 110 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc, 111 111 PSR_WAIT_LINE_FLAG_TIMEOUT_MS); 112 112 if (ret) { 113 - dev_err(dp->dev, "line flag interrupt did not arrive\n"); 113 + DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n"); 114 114 return; 115 115 } 116 116 ··· 140 140 141 141 ret = clk_prepare_enable(dp->pclk); 142 142 if (ret < 0) { 143 - dev_err(dp->dev, "failed to enable pclk %d\n", ret); 143 + DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret); 144 144 return ret; 145 145 } 146 146 147 147 ret = rockchip_dp_pre_init(dp); 148 148 if (ret < 0) { 149 - dev_err(dp->dev, "failed to dp pre init %d\n", ret); 149 + DRM_DEV_ERROR(dp->dev, "failed to dp pre init %d\n", ret); 150 150 clk_disable_unprepare(dp->pclk); 151 151 return ret; 152 152 } ··· 211 211 else 212 212 val = dp->data->lcdsel_big; 213 213 214 - dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); 214 + DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); 215 215 216 216 ret = clk_prepare_enable(dp->grfclk); 217 217 if (ret < 0) { 218 - dev_err(dp->dev, "failed to enable grfclk %d\n", ret); 218 + DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret); 219 219 return; 220 220 } 221 221 222 222 ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val); 223 223 if (ret != 0) 224 - dev_err(dp->dev, "Could not write to GRF: %d\n", ret); 224 + DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret); 225 225 226 226 clk_disable_unprepare(dp->grfclk); 227 227 } ··· 277 277 278 278 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 279 279 if (IS_ERR(dp->grf)) { 280 - dev_err(dev, "failed to get rockchip,grf property\n"); 280 + DRM_DEV_ERROR(dev, "failed to get rockchip,grf property\n"); 281 281 return PTR_ERR(dp->grf); 282 282 } 283 283 ··· 287 287 } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) { 288 288 return -EPROBE_DEFER; 289 289 } else if (IS_ERR(dp->grfclk)) { 290 - dev_err(dev, "failed to get grf clock\n"); 290 + DRM_DEV_ERROR(dev, "failed to get grf clock\n"); 291 291 return PTR_ERR(dp->grfclk); 292 292 } 293 293 294 294 dp->pclk = devm_clk_get(dev, "pclk"); 295 295 if (IS_ERR(dp->pclk)) { 296 - dev_err(dev, "failed to get pclk property\n"); 296 + DRM_DEV_ERROR(dev, "failed to get pclk property\n"); 297 297 return PTR_ERR(dp->pclk); 298 298 } 299 299 300 300 dp->rst = devm_reset_control_get(dev, "dp"); 301 301 if (IS_ERR(dp->rst)) { 302 - dev_err(dev, "failed to get dp reset control\n"); 302 + DRM_DEV_ERROR(dev, "failed to get dp reset control\n"); 303 303 return PTR_ERR(dp->rst); 304 304 } 305 305 306 306 ret = clk_prepare_enable(dp->pclk); 307 307 if (ret < 0) { 308 - dev_err(dp->dev, "failed to enable pclk %d\n", ret); 308 + DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret); 309 309 return ret; 310 310 } 311 311 312 312 ret = rockchip_dp_pre_init(dp); 313 313 if (ret < 0) { 314 - dev_err(dp->dev, "failed to pre init %d\n", ret); 314 + DRM_DEV_ERROR(dp->dev, "failed to pre init %d\n", ret); 315 315 clk_disable_unprepare(dp->pclk); 316 316 return ret; 317 317 }
+1 -1
drivers/gpu/drm/rockchip/cdn-dp-reg.c
··· 323 323 reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff; 324 324 dp->fw_version |= reg << 24; 325 325 326 - dev_dbg(dp->dev, "firmware version: %x\n", dp->fw_version); 326 + DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version); 327 327 328 328 return 0; 329 329 }
+48 -38
drivers/gpu/drm/rockchip/dw-mipi-dsi.c
··· 430 430 431 431 testdin = max_mbps_to_testdin(dsi->lane_mbps); 432 432 if (testdin < 0) { 433 - dev_err(dsi->dev, 434 - "failed to get testdin for %dmbps lane clock\n", 435 - dsi->lane_mbps); 433 + DRM_DEV_ERROR(dsi->dev, 434 + "failed to get testdin for %dmbps lane clock\n", 435 + dsi->lane_mbps); 436 436 return testdin; 437 437 } 438 438 ··· 443 443 444 444 ret = clk_prepare_enable(dsi->phy_cfg_clk); 445 445 if (ret) { 446 - dev_err(dsi->dev, "Failed to enable phy_cfg_clk\n"); 446 + DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n"); 447 447 return ret; 448 448 } 449 449 ··· 501 501 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 502 502 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US); 503 503 if (ret < 0) { 504 - dev_err(dsi->dev, "failed to wait for phy lock state\n"); 504 + DRM_DEV_ERROR(dsi->dev, "failed to wait for phy lock state\n"); 505 505 goto phy_init_end; 506 506 } 507 507 ··· 509 509 val, val & STOP_STATE_CLK_LANE, 1000, 510 510 PHY_STATUS_TIMEOUT_US); 511 511 if (ret < 0) 512 - dev_err(dsi->dev, 513 - "failed to wait for phy clk lane stop state\n"); 512 + DRM_DEV_ERROR(dsi->dev, 513 + "failed to wait for phy clk lane stop state\n"); 514 514 515 515 phy_init_end: 516 516 clk_disable_unprepare(dsi->phy_cfg_clk); ··· 529 529 530 530 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); 531 531 if (bpp < 0) { 532 - dev_err(dsi->dev, "failed to get bpp for pixel format %d\n", 533 - dsi->format); 532 + DRM_DEV_ERROR(dsi->dev, 533 + "failed to get bpp for pixel format %d\n", 534 + dsi->format); 534 535 return bpp; 535 536 } 536 537 ··· 542 541 if (tmp < max_mbps) 543 542 target_mbps = tmp; 544 543 else 545 - dev_err(dsi->dev, "DPHY clock frequency is out of range\n"); 544 + DRM_DEV_ERROR(dsi->dev, 545 + "DPHY clock frequency is out of range\n"); 546 546 } 547 547 548 548 pllref = DIV_ROUND_UP(clk_get_rate(dsi->pllref_clk), USEC_PER_SEC); ··· 584 582 struct dw_mipi_dsi *dsi = host_to_dsi(host); 585 583 586 584 if (device->lanes > dsi->pdata->max_data_lanes) { 587 - dev_err(dsi->dev, "the number of data lanes(%u) is too many\n", 588 - device->lanes); 585 + DRM_DEV_ERROR(dsi->dev, 586 + "the number of data lanes(%u) is too many\n", 587 + device->lanes); 589 588 return -EINVAL; 590 589 } 591 590 ··· 635 632 val, !(val & GEN_CMD_FULL), 1000, 636 633 CMD_PKT_STATUS_TIMEOUT_US); 637 634 if (ret < 0) { 638 - dev_err(dsi->dev, "failed to get available command FIFO\n"); 635 + DRM_DEV_ERROR(dsi->dev, 636 + "failed to get available command FIFO\n"); 639 637 return ret; 640 638 } 641 639 ··· 647 643 val, (val & mask) == mask, 648 644 1000, CMD_PKT_STATUS_TIMEOUT_US); 649 645 if (ret < 0) { 650 - dev_err(dsi->dev, "failed to write command FIFO\n"); 646 + DRM_DEV_ERROR(dsi->dev, "failed to write command FIFO\n"); 651 647 return ret; 652 648 } 653 649 ··· 667 663 data |= tx_buf[1] << 8; 668 664 669 665 if (msg->tx_len > 2) { 670 - dev_err(dsi->dev, "too long tx buf length %zu for short write\n", 671 - msg->tx_len); 666 + DRM_DEV_ERROR(dsi->dev, 667 + "too long tx buf length %zu for short write\n", 668 + msg->tx_len); 672 669 return -EINVAL; 673 670 } 674 671 ··· 687 682 u32 val; 688 683 689 684 if (msg->tx_len < 3) { 690 - dev_err(dsi->dev, "wrong tx buf length %zu for long write\n", 691 - msg->tx_len); 685 + DRM_DEV_ERROR(dsi->dev, 686 + "wrong tx buf length %zu for long write\n", 687 + msg->tx_len); 692 688 return -EINVAL; 693 689 } 694 690 ··· 710 704 val, !(val & GEN_PLD_W_FULL), 1000, 711 705 CMD_PKT_STATUS_TIMEOUT_US); 712 706 if (ret < 0) { 713 - dev_err(dsi->dev, 714 - "failed to get available write payload FIFO\n"); 707 + DRM_DEV_ERROR(dsi->dev, 708 + "failed to get available write payload FIFO\n"); 715 709 return ret; 716 710 } 717 711 } ··· 737 731 ret = dw_mipi_dsi_dcs_long_write(dsi, msg); 738 732 break; 739 733 default: 740 - dev_err(dsi->dev, "unsupported message type 0x%02x\n", 741 - msg->type); 734 + DRM_DEV_ERROR(dsi->dev, "unsupported message type 0x%02x\n", 735 + msg->type); 742 736 ret = -EINVAL; 743 737 } 744 738 ··· 941 935 return; 942 936 943 937 if (clk_prepare_enable(dsi->pclk)) { 944 - dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__); 938 + DRM_DEV_ERROR(dsi->dev, "Failed to enable pclk\n"); 945 939 return; 946 940 } 947 941 ··· 973 967 return; 974 968 975 969 if (clk_prepare_enable(dsi->pclk)) { 976 - dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__); 970 + DRM_DEV_ERROR(dsi->dev, "Failed to enable pclk\n"); 977 971 return; 978 972 } 979 973 ··· 997 991 */ 998 992 ret = clk_prepare_enable(dsi->grf_clk); 999 993 if (ret) { 1000 - dev_err(dsi->dev, "Failed to enable grf_clk: %d\n", ret); 994 + DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); 1001 995 return; 1002 996 } 1003 997 ··· 1010 1004 1011 1005 dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE); 1012 1006 if (drm_panel_prepare(dsi->panel)) 1013 - dev_err(dsi->dev, "failed to prepare panel\n"); 1007 + DRM_DEV_ERROR(dsi->dev, "failed to prepare panel\n"); 1014 1008 1015 1009 dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE); 1016 1010 drm_panel_enable(dsi->panel); ··· 1023 1017 val = pdata->dsi0_en_bit << 16; 1024 1018 1025 1019 regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val); 1026 - dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG"); 1020 + DRM_DEV_DEBUG(dsi->dev, 1021 + "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG"); 1027 1022 dsi->dpms_mode = DRM_MODE_DPMS_ON; 1028 1023 1029 1024 clk_disable_unprepare(dsi->grf_clk); ··· 1118 1111 ret = drm_encoder_init(drm, &dsi->encoder, &dw_mipi_dsi_encoder_funcs, 1119 1112 DRM_MODE_ENCODER_DSI, NULL); 1120 1113 if (ret) { 1121 - dev_err(dev, "Failed to initialize encoder with drm\n"); 1114 + DRM_DEV_ERROR(dev, "Failed to initialize encoder with drm\n"); 1122 1115 return ret; 1123 1116 } 1124 1117 ··· 1140 1133 1141 1134 dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 1142 1135 if (IS_ERR(dsi->grf_regmap)) { 1143 - dev_err(dsi->dev, "Unable to get rockchip,grf\n"); 1136 + DRM_DEV_ERROR(dsi->dev, "Unable to get rockchip,grf\n"); 1144 1137 return PTR_ERR(dsi->grf_regmap); 1145 1138 } 1146 1139 ··· 1212 1205 dsi->pllref_clk = devm_clk_get(dev, "ref"); 1213 1206 if (IS_ERR(dsi->pllref_clk)) { 1214 1207 ret = PTR_ERR(dsi->pllref_clk); 1215 - dev_err(dev, "Unable to get pll reference clock: %d\n", ret); 1208 + DRM_DEV_ERROR(dev, 1209 + "Unable to get pll reference clock: %d\n", ret); 1216 1210 return ret; 1217 1211 } 1218 1212 1219 1213 dsi->pclk = devm_clk_get(dev, "pclk"); 1220 1214 if (IS_ERR(dsi->pclk)) { 1221 1215 ret = PTR_ERR(dsi->pclk); 1222 - dev_err(dev, "Unable to get pclk: %d\n", ret); 1216 + DRM_DEV_ERROR(dev, "Unable to get pclk: %d\n", ret); 1223 1217 return ret; 1224 1218 } 1225 1219 ··· 1234 1226 if (ret == -ENOENT) { 1235 1227 apb_rst = NULL; 1236 1228 } else { 1237 - dev_err(dev, "Unable to get reset control: %d\n", ret); 1229 + DRM_DEV_ERROR(dev, 1230 + "Unable to get reset control: %d\n", ret); 1238 1231 return ret; 1239 1232 } 1240 1233 } ··· 1243 1234 if (apb_rst) { 1244 1235 ret = clk_prepare_enable(dsi->pclk); 1245 1236 if (ret) { 1246 - dev_err(dev, "%s: Failed to enable pclk\n", __func__); 1237 + DRM_DEV_ERROR(dev, "Failed to enable pclk\n"); 1247 1238 return ret; 1248 1239 } 1249 1240 ··· 1258 1249 dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg"); 1259 1250 if (IS_ERR(dsi->phy_cfg_clk)) { 1260 1251 ret = PTR_ERR(dsi->phy_cfg_clk); 1261 - dev_err(dev, "Unable to get phy_cfg_clk: %d\n", ret); 1252 + DRM_DEV_ERROR(dev, 1253 + "Unable to get phy_cfg_clk: %d\n", ret); 1262 1254 return ret; 1263 1255 } 1264 1256 } ··· 1268 1258 dsi->grf_clk = devm_clk_get(dev, "grf"); 1269 1259 if (IS_ERR(dsi->grf_clk)) { 1270 1260 ret = PTR_ERR(dsi->grf_clk); 1271 - dev_err(dev, "Unable to get grf_clk: %d\n", ret); 1261 + DRM_DEV_ERROR(dev, "Unable to get grf_clk: %d\n", ret); 1272 1262 return ret; 1273 1263 } 1274 1264 } 1275 1265 1276 1266 ret = clk_prepare_enable(dsi->pllref_clk); 1277 1267 if (ret) { 1278 - dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__); 1268 + DRM_DEV_ERROR(dev, "Failed to enable pllref_clk\n"); 1279 1269 return ret; 1280 1270 } 1281 1271 1282 1272 ret = dw_mipi_dsi_register(drm, dsi); 1283 1273 if (ret) { 1284 - dev_err(dev, "Failed to register mipi_dsi: %d\n", ret); 1274 + DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret); 1285 1275 goto err_pllref; 1286 1276 } 1287 1277 ··· 1291 1281 dsi->dsi_host.dev = dev; 1292 1282 ret = mipi_dsi_host_register(&dsi->dsi_host); 1293 1283 if (ret) { 1294 - dev_err(dev, "Failed to register MIPI host: %d\n", ret); 1284 + DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret); 1295 1285 goto err_cleanup; 1296 1286 } 1297 1287
+10 -9
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
··· 168 168 169 169 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 170 170 if (IS_ERR(hdmi->regmap)) { 171 - dev_err(hdmi->dev, "Unable to get rockchip,grf\n"); 171 + DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n"); 172 172 return PTR_ERR(hdmi->regmap); 173 173 } 174 174 ··· 178 178 } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) { 179 179 return -EPROBE_DEFER; 180 180 } else if (IS_ERR(hdmi->vpll_clk)) { 181 - dev_err(hdmi->dev, "failed to get grf clock\n"); 181 + DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n"); 182 182 return PTR_ERR(hdmi->vpll_clk); 183 183 } 184 184 ··· 188 188 } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) { 189 189 return -EPROBE_DEFER; 190 190 } else if (IS_ERR(hdmi->grf_clk)) { 191 - dev_err(hdmi->dev, "failed to get grf clock\n"); 191 + DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n"); 192 192 return PTR_ERR(hdmi->grf_clk); 193 193 } 194 194 195 195 ret = clk_prepare_enable(hdmi->vpll_clk); 196 196 if (ret) { 197 - dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret); 197 + DRM_DEV_ERROR(hdmi->dev, 198 + "Failed to enable HDMI vpll: %d\n", ret); 198 199 return ret; 199 200 } 200 201 ··· 260 259 261 260 ret = clk_prepare_enable(hdmi->grf_clk); 262 261 if (ret < 0) { 263 - dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret); 262 + DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret); 264 263 return; 265 264 } 266 265 267 266 ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val); 268 267 if (ret != 0) 269 - dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret); 268 + DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret); 270 269 271 270 clk_disable_unprepare(hdmi->grf_clk); 272 - dev_dbg(hdmi->dev, "vop %s output to hdmi\n", 273 - ret ? "LIT" : "BIG"); 271 + DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n", 272 + ret ? "LIT" : "BIG"); 274 273 } 275 274 276 275 static int ··· 369 368 370 369 ret = rockchip_hdmi_parse_dt(hdmi); 371 370 if (ret) { 372 - dev_err(hdmi->dev, "Unable to parse OF data\n"); 371 + DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n"); 373 372 return ret; 374 373 } 375 374
+8 -6
drivers/gpu/drm/rockchip/inno_hdmi.c
··· 224 224 break; 225 225 226 226 default: 227 - dev_err(hdmi->dev, "Unknown power mode %d\n", mode); 227 + DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode); 228 228 } 229 229 } 230 230 ··· 742 742 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); 743 743 744 744 for (i = 0; i < num; i++) { 745 - dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", 746 - i + 1, num, msgs[i].len, msgs[i].flags); 745 + DRM_DEV_DEBUG(hdmi->dev, 746 + "xfer: num: %d/%d, len: %d, flags: %#x\n", 747 + i + 1, num, msgs[i].len, msgs[i].flags); 747 748 748 749 if (msgs[i].flags & I2C_M_RD) 749 750 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); ··· 807 806 808 807 hdmi->i2c = i2c; 809 808 810 - dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); 809 + DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name); 811 810 812 811 return adap; 813 812 } ··· 839 838 840 839 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); 841 840 if (IS_ERR(hdmi->pclk)) { 842 - dev_err(hdmi->dev, "Unable to get HDMI pclk clk\n"); 841 + DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n"); 843 842 return PTR_ERR(hdmi->pclk); 844 843 } 845 844 846 845 ret = clk_prepare_enable(hdmi->pclk); 847 846 if (ret) { 848 - dev_err(hdmi->dev, "Cannot enable HDMI pclk clock: %d\n", ret); 847 + DRM_DEV_ERROR(hdmi->dev, 848 + "Cannot enable HDMI pclk clock: %d\n", ret); 849 849 return ret; 850 850 } 851 851
+9 -5
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
··· 58 58 59 59 ret = iommu_attach_device(private->domain, dev); 60 60 if (ret) { 61 - dev_err(dev, "Failed to attach iommu device\n"); 61 + DRM_DEV_ERROR(dev, "Failed to attach iommu device\n"); 62 62 return ret; 63 63 } 64 64 ··· 373 373 374 374 iommu = of_parse_phandle(port->parent, "iommus", 0); 375 375 if (!iommu || !of_device_is_available(iommu->parent)) { 376 - dev_dbg(dev, "no iommu attached for %pOF, using non-iommu buffers\n", 377 - port->parent); 376 + DRM_DEV_DEBUG(dev, 377 + "no iommu attached for %pOF, using non-iommu buffers\n", 378 + port->parent); 378 379 /* 379 380 * if there is a crtc not support iommu, force set all 380 381 * crtc use non-iommu buffer. ··· 390 389 } 391 390 392 391 if (i == 0) { 393 - dev_err(dev, "missing 'ports' property\n"); 392 + DRM_DEV_ERROR(dev, "missing 'ports' property\n"); 394 393 return -ENODEV; 395 394 } 396 395 397 396 if (!found) { 398 - dev_err(dev, "No available vop found for display-subsystem.\n"); 397 + DRM_DEV_ERROR(dev, 398 + "No available vop found for display-subsystem.\n"); 399 399 return -ENODEV; 400 400 } 401 401 ··· 455 453 456 454 num_rockchip_sub_drivers = 0; 457 455 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP); 456 + ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver, 457 + CONFIG_ROCKCHIP_LVDS); 458 458 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, 459 459 CONFIG_ROCKCHIP_ANALOGIX_DP); 460 460 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP);
+1
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
··· 69 69 extern struct platform_driver dw_mipi_dsi_driver; 70 70 extern struct platform_driver inno_hdmi_driver; 71 71 extern struct platform_driver rockchip_dp_driver; 72 + extern struct platform_driver rockchip_lvds_driver; 72 73 extern struct platform_driver vop_platform_driver; 73 74 #endif /* _ROCKCHIP_DRM_DRV_H_ */
+5 -3
drivers/gpu/drm/rockchip/rockchip_drm_fb.c
··· 100 100 ret = drm_framebuffer_init(dev, &rockchip_fb->fb, 101 101 &rockchip_drm_fb_funcs); 102 102 if (ret) { 103 - dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", 104 - ret); 103 + DRM_DEV_ERROR(dev->dev, 104 + "Failed to initialize framebuffer: %d\n", 105 + ret); 105 106 kfree(rockchip_fb); 106 107 return ERR_PTR(ret); 107 108 } ··· 135 134 136 135 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); 137 136 if (!obj) { 138 - dev_err(dev->dev, "Failed to lookup GEM object\n"); 137 + DRM_DEV_ERROR(dev->dev, 138 + "Failed to lookup GEM object\n"); 139 139 ret = -ENXIO; 140 140 goto err_gem_object_unreference; 141 141 }
+11 -7
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
··· 76 76 77 77 fbi = drm_fb_helper_alloc_fbi(helper); 78 78 if (IS_ERR(fbi)) { 79 - dev_err(dev->dev, "Failed to create framebuffer info.\n"); 79 + DRM_DEV_ERROR(dev->dev, "Failed to create framebuffer info.\n"); 80 80 ret = PTR_ERR(fbi); 81 81 goto out; 82 82 } ··· 84 84 helper->fb = rockchip_drm_framebuffer_init(dev, &mode_cmd, 85 85 private->fbdev_bo); 86 86 if (IS_ERR(helper->fb)) { 87 - dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); 87 + DRM_DEV_ERROR(dev->dev, 88 + "Failed to allocate DRM framebuffer.\n"); 88 89 ret = PTR_ERR(helper->fb); 89 90 goto out; 90 91 } ··· 139 138 140 139 ret = drm_fb_helper_init(dev, helper, ROCKCHIP_MAX_CONNECTOR); 141 140 if (ret < 0) { 142 - dev_err(dev->dev, "Failed to initialize drm fb helper - %d.\n", 143 - ret); 141 + DRM_DEV_ERROR(dev->dev, 142 + "Failed to initialize drm fb helper - %d.\n", 143 + ret); 144 144 return ret; 145 145 } 146 146 147 147 ret = drm_fb_helper_single_add_all_connectors(helper); 148 148 if (ret < 0) { 149 - dev_err(dev->dev, "Failed to add connectors - %d.\n", ret); 149 + DRM_DEV_ERROR(dev->dev, 150 + "Failed to add connectors - %d.\n", ret); 150 151 goto err_drm_fb_helper_fini; 151 152 } 152 153 153 154 ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); 154 155 if (ret < 0) { 155 - dev_err(dev->dev, "Failed to set initial hw config - %d.\n", 156 - ret); 156 + DRM_DEV_ERROR(dev->dev, 157 + "Failed to set initial hw config - %d.\n", 158 + ret); 157 159 goto err_drm_fb_helper_fini; 158 160 } 159 161
+17 -15
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
··· 160 160 int offset, mask, shift; 161 161 162 162 if (!reg || !reg->mask) { 163 - dev_dbg(vop->dev, "Warning: not support %s\n", reg_name); 163 + DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name); 164 164 return; 165 165 } 166 166 ··· 499 499 500 500 ret = pm_runtime_get_sync(vop->dev); 501 501 if (ret < 0) { 502 - dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); 502 + DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret); 503 503 return ret; 504 504 } 505 505 ··· 523 523 */ 524 524 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev); 525 525 if (ret) { 526 - dev_err(vop->dev, "failed to attach dma mapping, %d\n", ret); 526 + DRM_DEV_ERROR(vop->dev, 527 + "failed to attach dma mapping, %d\n", ret); 527 528 goto err_disable_aclk; 528 529 } 529 530 ··· 1362 1361 1363 1362 vop->hclk = devm_clk_get(vop->dev, "hclk_vop"); 1364 1363 if (IS_ERR(vop->hclk)) { 1365 - dev_err(vop->dev, "failed to get hclk source\n"); 1364 + DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n"); 1366 1365 return PTR_ERR(vop->hclk); 1367 1366 } 1368 1367 vop->aclk = devm_clk_get(vop->dev, "aclk_vop"); 1369 1368 if (IS_ERR(vop->aclk)) { 1370 - dev_err(vop->dev, "failed to get aclk source\n"); 1369 + DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n"); 1371 1370 return PTR_ERR(vop->aclk); 1372 1371 } 1373 1372 vop->dclk = devm_clk_get(vop->dev, "dclk_vop"); 1374 1373 if (IS_ERR(vop->dclk)) { 1375 - dev_err(vop->dev, "failed to get dclk source\n"); 1374 + DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n"); 1376 1375 return PTR_ERR(vop->dclk); 1377 1376 } 1378 1377 1379 1378 ret = pm_runtime_get_sync(vop->dev); 1380 1379 if (ret < 0) { 1381 - dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); 1380 + DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret); 1382 1381 return ret; 1383 1382 } 1384 1383 1385 1384 ret = clk_prepare(vop->dclk); 1386 1385 if (ret < 0) { 1387 - dev_err(vop->dev, "failed to prepare dclk\n"); 1386 + DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n"); 1388 1387 goto err_put_pm_runtime; 1389 1388 } 1390 1389 1391 1390 /* Enable both the hclk and aclk to setup the vop */ 1392 1391 ret = clk_prepare_enable(vop->hclk); 1393 1392 if (ret < 0) { 1394 - dev_err(vop->dev, "failed to prepare/enable hclk\n"); 1393 + DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n"); 1395 1394 goto err_unprepare_dclk; 1396 1395 } 1397 1396 1398 1397 ret = clk_prepare_enable(vop->aclk); 1399 1398 if (ret < 0) { 1400 - dev_err(vop->dev, "failed to prepare/enable aclk\n"); 1399 + DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n"); 1401 1400 goto err_disable_hclk; 1402 1401 } 1403 1402 ··· 1406 1405 */ 1407 1406 ahb_rst = devm_reset_control_get(vop->dev, "ahb"); 1408 1407 if (IS_ERR(ahb_rst)) { 1409 - dev_err(vop->dev, "failed to get ahb reset\n"); 1408 + DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n"); 1410 1409 ret = PTR_ERR(ahb_rst); 1411 1410 goto err_disable_aclk; 1412 1411 } ··· 1435 1434 */ 1436 1435 vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk"); 1437 1436 if (IS_ERR(vop->dclk_rst)) { 1438 - dev_err(vop->dev, "failed to get dclk reset\n"); 1437 + DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n"); 1439 1438 ret = PTR_ERR(vop->dclk_rst); 1440 1439 goto err_disable_aclk; 1441 1440 } ··· 1512 1511 vop_line_flag_irq_disable(vop); 1513 1512 1514 1513 if (jiffies_left == 0) { 1515 - dev_err(vop->dev, "Timeout waiting for IRQ\n"); 1514 + DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n"); 1516 1515 return -ETIMEDOUT; 1517 1516 } 1518 1517 ··· 1559 1558 1560 1559 irq = platform_get_irq(pdev, 0); 1561 1560 if (irq < 0) { 1562 - dev_err(dev, "cannot find irq for vop\n"); 1561 + DRM_DEV_ERROR(dev, "cannot find irq for vop\n"); 1563 1562 return irq; 1564 1563 } 1565 1564 vop->irq = (unsigned int)irq; ··· 1585 1584 1586 1585 ret = vop_initial(vop); 1587 1586 if (ret < 0) { 1588 - dev_err(&pdev->dev, "cannot initial vop dev - err %d\n", ret); 1587 + DRM_DEV_ERROR(&pdev->dev, 1588 + "cannot initial vop dev - err %d\n", ret); 1589 1589 goto err_disable_pm_runtime; 1590 1590 } 1591 1591
+581
drivers/gpu/drm/rockchip/rockchip_lvds.c
··· 1 + /* 2 + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 + * Author: 4 + * Mark Yao <mark.yao@rock-chips.com> 5 + * Sandy Huang <hjc@rock-chips.com> 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <drm/drmP.h> 18 + #include <drm/drm_atomic_helper.h> 19 + #include <drm/drm_crtc_helper.h> 20 + #include <drm/drm_dp_helper.h> 21 + #include <drm/drm_panel.h> 22 + #include <drm/drm_of.h> 23 + 24 + #include <linux/component.h> 25 + #include <linux/clk.h> 26 + #include <linux/mfd/syscon.h> 27 + #include <linux/of_graph.h> 28 + #include <linux/pm_runtime.h> 29 + #include <linux/regmap.h> 30 + #include <linux/reset.h> 31 + 32 + #include "rockchip_drm_drv.h" 33 + #include "rockchip_drm_vop.h" 34 + #include "rockchip_lvds.h" 35 + 36 + #define DISPLAY_OUTPUT_RGB 0 37 + #define DISPLAY_OUTPUT_LVDS 1 38 + #define DISPLAY_OUTPUT_DUAL_LVDS 2 39 + 40 + #define connector_to_lvds(c) \ 41 + container_of(c, struct rockchip_lvds, connector) 42 + 43 + #define encoder_to_lvds(c) \ 44 + container_of(c, struct rockchip_lvds, encoder) 45 + 46 + /** 47 + * rockchip_lvds_soc_data - rockchip lvds Soc private data 48 + * @ch1_offset: lvds channel 1 registe offset 49 + * grf_soc_con6: general registe offset for LVDS contrl 50 + * grf_soc_con7: general registe offset for LVDS contrl 51 + * has_vop_sel: to indicate whether need to choose from different VOP. 52 + */ 53 + struct rockchip_lvds_soc_data { 54 + u32 ch1_offset; 55 + int grf_soc_con6; 56 + int grf_soc_con7; 57 + bool has_vop_sel; 58 + }; 59 + 60 + struct rockchip_lvds { 61 + struct device *dev; 62 + void __iomem *regs; 63 + struct regmap *grf; 64 + struct clk *pclk; 65 + const struct rockchip_lvds_soc_data *soc_data; 66 + int output; /* rgb lvds or dual lvds output */ 67 + int format; /* vesa or jeida format */ 68 + struct drm_device *drm_dev; 69 + struct drm_panel *panel; 70 + struct drm_bridge *bridge; 71 + struct drm_connector connector; 72 + struct drm_encoder encoder; 73 + struct dev_pin_info *pins; 74 + }; 75 + 76 + static inline void lvds_writel(struct rockchip_lvds *lvds, u32 offset, u32 val) 77 + { 78 + writel_relaxed(val, lvds->regs + offset); 79 + if (lvds->output == DISPLAY_OUTPUT_LVDS) 80 + return; 81 + writel_relaxed(val, lvds->regs + offset + lvds->soc_data->ch1_offset); 82 + } 83 + 84 + static inline int lvds_name_to_format(const char *s) 85 + { 86 + if (strncmp(s, "jeida-18", 8) == 0) 87 + return LVDS_JEIDA_18; 88 + else if (strncmp(s, "jeida-24", 8) == 0) 89 + return LVDS_JEIDA_24; 90 + else if (strncmp(s, "vesa-24", 7) == 0) 91 + return LVDS_VESA_24; 92 + 93 + return -EINVAL; 94 + } 95 + 96 + static inline int lvds_name_to_output(const char *s) 97 + { 98 + if (strncmp(s, "rgb", 3) == 0) 99 + return DISPLAY_OUTPUT_RGB; 100 + else if (strncmp(s, "lvds", 4) == 0) 101 + return DISPLAY_OUTPUT_LVDS; 102 + else if (strncmp(s, "duallvds", 8) == 0) 103 + return DISPLAY_OUTPUT_DUAL_LVDS; 104 + 105 + return -EINVAL; 106 + } 107 + 108 + static int rockchip_lvds_poweron(struct rockchip_lvds *lvds) 109 + { 110 + int ret; 111 + u32 val; 112 + 113 + ret = clk_enable(lvds->pclk); 114 + if (ret < 0) { 115 + DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret); 116 + return ret; 117 + } 118 + ret = pm_runtime_get_sync(lvds->dev); 119 + if (ret < 0) { 120 + DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 121 + clk_disable(lvds->pclk); 122 + return ret; 123 + } 124 + val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN | 125 + RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN | 126 + RK3288_LVDS_CH0_REG0_LANE0_EN; 127 + if (lvds->output == DISPLAY_OUTPUT_RGB) { 128 + val |= RK3288_LVDS_CH0_REG0_TTL_EN | 129 + RK3288_LVDS_CH0_REG0_LANECK_EN; 130 + lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); 131 + lvds_writel(lvds, RK3288_LVDS_CH0_REG2, 132 + RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 133 + lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 134 + RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE | 135 + RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE | 136 + RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE | 137 + RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE | 138 + RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE | 139 + RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE); 140 + lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 141 + RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA | 142 + RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA | 143 + RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA | 144 + RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA | 145 + RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA | 146 + RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA); 147 + } else { 148 + val |= RK3288_LVDS_CH0_REG0_LVDS_EN | 149 + RK3288_LVDS_CH0_REG0_LANECK_EN; 150 + lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); 151 + lvds_writel(lvds, RK3288_LVDS_CH0_REG1, 152 + RK3288_LVDS_CH0_REG1_LANECK_BIAS | 153 + RK3288_LVDS_CH0_REG1_LANE4_BIAS | 154 + RK3288_LVDS_CH0_REG1_LANE3_BIAS | 155 + RK3288_LVDS_CH0_REG1_LANE2_BIAS | 156 + RK3288_LVDS_CH0_REG1_LANE1_BIAS | 157 + RK3288_LVDS_CH0_REG1_LANE0_BIAS); 158 + lvds_writel(lvds, RK3288_LVDS_CH0_REG2, 159 + RK3288_LVDS_CH0_REG2_RESERVE_ON | 160 + RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE | 161 + RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE | 162 + RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE | 163 + RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE | 164 + RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE | 165 + RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE | 166 + RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 167 + lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00); 168 + lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00); 169 + } 170 + lvds_writel(lvds, RK3288_LVDS_CH0_REG3, RK3288_LVDS_PLL_FBDIV_REG3(0x46)); 171 + lvds_writel(lvds, RK3288_LVDS_CH0_REGD, RK3288_LVDS_PLL_PREDIV_REGD(0x0a)); 172 + lvds_writel(lvds, RK3288_LVDS_CH0_REG20, RK3288_LVDS_CH0_REG20_LSB); 173 + 174 + lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); 175 + lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); 176 + 177 + return 0; 178 + } 179 + 180 + static void rockchip_lvds_poweroff(struct rockchip_lvds *lvds) 181 + { 182 + int ret; 183 + u32 val; 184 + 185 + lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); 186 + lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); 187 + val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN; 188 + val |= val << 16; 189 + ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); 190 + if (ret != 0) 191 + DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 192 + 193 + pm_runtime_put(lvds->dev); 194 + clk_disable(lvds->pclk); 195 + } 196 + 197 + static const struct drm_connector_funcs rockchip_lvds_connector_funcs = { 198 + .fill_modes = drm_helper_probe_single_connector_modes, 199 + .destroy = drm_connector_cleanup, 200 + .reset = drm_atomic_helper_connector_reset, 201 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 202 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 203 + }; 204 + 205 + static int rockchip_lvds_connector_get_modes(struct drm_connector *connector) 206 + { 207 + struct rockchip_lvds *lvds = connector_to_lvds(connector); 208 + struct drm_panel *panel = lvds->panel; 209 + 210 + return drm_panel_get_modes(panel); 211 + } 212 + 213 + static const 214 + struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = { 215 + .get_modes = rockchip_lvds_connector_get_modes, 216 + }; 217 + 218 + static void rockchip_lvds_grf_config(struct drm_encoder *encoder, 219 + struct drm_display_mode *mode) 220 + { 221 + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 222 + u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0; 223 + u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0; 224 + u32 val; 225 + int ret; 226 + 227 + /* iomux to LCD data/sync mode */ 228 + if (lvds->output == DISPLAY_OUTPUT_RGB) 229 + if (lvds->pins && !IS_ERR(lvds->pins->default_state)) 230 + pinctrl_select_state(lvds->pins->p, 231 + lvds->pins->default_state); 232 + val = lvds->format | LVDS_CH0_EN; 233 + if (lvds->output == DISPLAY_OUTPUT_RGB) 234 + val |= LVDS_TTL_EN | LVDS_CH1_EN; 235 + else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS) 236 + val |= LVDS_DUAL | LVDS_CH1_EN; 237 + 238 + if ((mode->htotal - mode->hsync_start) & 0x01) 239 + val |= LVDS_START_PHASE_RST_1; 240 + 241 + val |= (pin_dclk << 8) | (pin_hsync << 9); 242 + val |= (0xffff << 16); 243 + ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); 244 + if (ret != 0) { 245 + DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 246 + return; 247 + } 248 + } 249 + 250 + static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds, 251 + struct drm_encoder *encoder) 252 + { 253 + u32 val; 254 + int ret; 255 + 256 + if (!lvds->soc_data->has_vop_sel) 257 + return 0; 258 + 259 + ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); 260 + if (ret < 0) 261 + return ret; 262 + 263 + val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16; 264 + if (ret) 265 + val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT; 266 + 267 + ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con6, val); 268 + if (ret < 0) 269 + return ret; 270 + 271 + return 0; 272 + } 273 + 274 + static int 275 + rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder, 276 + struct drm_crtc_state *crtc_state, 277 + struct drm_connector_state *conn_state) 278 + { 279 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 280 + 281 + s->output_mode = ROCKCHIP_OUT_MODE_P888; 282 + s->output_type = DRM_MODE_CONNECTOR_LVDS; 283 + 284 + return 0; 285 + } 286 + 287 + static void rockchip_lvds_encoder_enable(struct drm_encoder *encoder) 288 + { 289 + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 290 + struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 291 + int ret; 292 + 293 + drm_panel_prepare(lvds->panel); 294 + ret = rockchip_lvds_poweron(lvds); 295 + if (ret < 0) { 296 + DRM_DEV_ERROR(lvds->dev, "failed to power on lvds: %d\n", ret); 297 + drm_panel_unprepare(lvds->panel); 298 + } 299 + rockchip_lvds_grf_config(encoder, mode); 300 + rockchip_lvds_set_vop_source(lvds, encoder); 301 + drm_panel_enable(lvds->panel); 302 + } 303 + 304 + static void rockchip_lvds_encoder_disable(struct drm_encoder *encoder) 305 + { 306 + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 307 + 308 + drm_panel_disable(lvds->panel); 309 + rockchip_lvds_poweroff(lvds); 310 + drm_panel_unprepare(lvds->panel); 311 + } 312 + 313 + static const 314 + struct drm_encoder_helper_funcs rockchip_lvds_encoder_helper_funcs = { 315 + .enable = rockchip_lvds_encoder_enable, 316 + .disable = rockchip_lvds_encoder_disable, 317 + .atomic_check = rockchip_lvds_encoder_atomic_check, 318 + }; 319 + 320 + static const struct drm_encoder_funcs rockchip_lvds_encoder_funcs = { 321 + .destroy = drm_encoder_cleanup, 322 + }; 323 + 324 + static const struct rockchip_lvds_soc_data rk3288_lvds_data = { 325 + .ch1_offset = 0x100, 326 + .grf_soc_con6 = 0x025c, 327 + .grf_soc_con7 = 0x0260, 328 + .has_vop_sel = true, 329 + }; 330 + 331 + static const struct of_device_id rockchip_lvds_dt_ids[] = { 332 + { 333 + .compatible = "rockchip,rk3288-lvds", 334 + .data = &rk3288_lvds_data 335 + }, 336 + {} 337 + }; 338 + MODULE_DEVICE_TABLE(of, rockchip_lvds_dt_ids); 339 + 340 + static int rockchip_lvds_bind(struct device *dev, struct device *master, 341 + void *data) 342 + { 343 + struct rockchip_lvds *lvds = dev_get_drvdata(dev); 344 + struct drm_device *drm_dev = data; 345 + struct drm_encoder *encoder; 346 + struct drm_connector *connector; 347 + struct device_node *remote = NULL; 348 + struct device_node *port, *endpoint; 349 + int ret; 350 + const char *name; 351 + u32 endpoint_id; 352 + 353 + lvds->drm_dev = drm_dev; 354 + port = of_graph_get_port_by_id(dev->of_node, 1); 355 + if (!port) { 356 + DRM_DEV_ERROR(dev, 357 + "can't found port point, please init lvds panel port!\n"); 358 + return -EINVAL; 359 + } 360 + for_each_child_of_node(port, endpoint) { 361 + of_property_read_u32(endpoint, "reg", &endpoint_id); 362 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id, 363 + &lvds->panel, &lvds->bridge); 364 + if (!ret) 365 + break; 366 + } 367 + if (ret) { 368 + DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n"); 369 + ret = -EPROBE_DEFER; 370 + goto err_put_port; 371 + } 372 + if (lvds->panel) 373 + remote = lvds->panel->dev->of_node; 374 + else 375 + remote = lvds->bridge->of_node; 376 + if (of_property_read_string(dev->of_node, "rockchip,output", &name)) 377 + /* default set it as output rgb */ 378 + lvds->output = DISPLAY_OUTPUT_RGB; 379 + else 380 + lvds->output = lvds_name_to_output(name); 381 + 382 + if (lvds->output < 0) { 383 + DRM_DEV_ERROR(dev, "invalid output type [%s]\n", name); 384 + ret = lvds->output; 385 + goto err_put_remote; 386 + } 387 + 388 + if (of_property_read_string(remote, "data-mapping", &name)) 389 + /* default set it as format vesa 18 */ 390 + lvds->format = LVDS_VESA_18; 391 + else 392 + lvds->format = lvds_name_to_format(name); 393 + 394 + if (lvds->format < 0) { 395 + DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name); 396 + ret = lvds->format; 397 + goto err_put_remote; 398 + } 399 + 400 + encoder = &lvds->encoder; 401 + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, 402 + dev->of_node); 403 + 404 + ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs, 405 + DRM_MODE_ENCODER_LVDS, NULL); 406 + if (ret < 0) { 407 + DRM_DEV_ERROR(drm_dev->dev, 408 + "failed to initialize encoder: %d\n", ret); 409 + goto err_put_remote; 410 + } 411 + 412 + drm_encoder_helper_add(encoder, &rockchip_lvds_encoder_helper_funcs); 413 + 414 + if (lvds->panel) { 415 + connector = &lvds->connector; 416 + connector->dpms = DRM_MODE_DPMS_OFF; 417 + ret = drm_connector_init(drm_dev, connector, 418 + &rockchip_lvds_connector_funcs, 419 + DRM_MODE_CONNECTOR_LVDS); 420 + if (ret < 0) { 421 + DRM_DEV_ERROR(drm_dev->dev, 422 + "failed to initialize connector: %d\n", ret); 423 + goto err_free_encoder; 424 + } 425 + 426 + drm_connector_helper_add(connector, 427 + &rockchip_lvds_connector_helper_funcs); 428 + 429 + ret = drm_mode_connector_attach_encoder(connector, encoder); 430 + if (ret < 0) { 431 + DRM_DEV_ERROR(drm_dev->dev, 432 + "failed to attach encoder: %d\n", ret); 433 + goto err_free_connector; 434 + } 435 + 436 + ret = drm_panel_attach(lvds->panel, connector); 437 + if (ret < 0) { 438 + DRM_DEV_ERROR(drm_dev->dev, 439 + "failed to attach panel: %d\n", ret); 440 + goto err_free_connector; 441 + } 442 + } else { 443 + lvds->bridge->encoder = encoder; 444 + ret = drm_bridge_attach(encoder, lvds->bridge, NULL); 445 + if (ret) { 446 + DRM_DEV_ERROR(drm_dev->dev, 447 + "failed to attach bridge: %d\n", ret); 448 + goto err_free_encoder; 449 + } 450 + encoder->bridge = lvds->bridge; 451 + } 452 + 453 + pm_runtime_enable(dev); 454 + of_node_put(remote); 455 + of_node_put(port); 456 + 457 + return 0; 458 + 459 + err_free_connector: 460 + drm_connector_cleanup(connector); 461 + err_free_encoder: 462 + drm_encoder_cleanup(encoder); 463 + err_put_remote: 464 + of_node_put(remote); 465 + err_put_port: 466 + of_node_put(port); 467 + 468 + return ret; 469 + } 470 + 471 + static void rockchip_lvds_unbind(struct device *dev, struct device *master, 472 + void *data) 473 + { 474 + struct rockchip_lvds *lvds = dev_get_drvdata(dev); 475 + 476 + rockchip_lvds_encoder_disable(&lvds->encoder); 477 + if (lvds->panel) 478 + drm_panel_detach(lvds->panel); 479 + pm_runtime_disable(dev); 480 + drm_connector_cleanup(&lvds->connector); 481 + drm_encoder_cleanup(&lvds->encoder); 482 + } 483 + 484 + static const struct component_ops rockchip_lvds_component_ops = { 485 + .bind = rockchip_lvds_bind, 486 + .unbind = rockchip_lvds_unbind, 487 + }; 488 + 489 + static int rockchip_lvds_probe(struct platform_device *pdev) 490 + { 491 + struct device *dev = &pdev->dev; 492 + struct rockchip_lvds *lvds; 493 + const struct of_device_id *match; 494 + struct resource *res; 495 + int ret; 496 + 497 + if (!dev->of_node) 498 + return -ENODEV; 499 + 500 + lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); 501 + if (!lvds) 502 + return -ENOMEM; 503 + 504 + lvds->dev = dev; 505 + match = of_match_node(rockchip_lvds_dt_ids, dev->of_node); 506 + if (!match) 507 + return -ENODEV; 508 + lvds->soc_data = match->data; 509 + 510 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 511 + lvds->regs = devm_ioremap_resource(&pdev->dev, res); 512 + if (IS_ERR(lvds->regs)) 513 + return PTR_ERR(lvds->regs); 514 + 515 + lvds->pclk = devm_clk_get(&pdev->dev, "pclk_lvds"); 516 + if (IS_ERR(lvds->pclk)) { 517 + DRM_DEV_ERROR(dev, "could not get pclk_lvds\n"); 518 + return PTR_ERR(lvds->pclk); 519 + } 520 + 521 + lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins), 522 + GFP_KERNEL); 523 + if (!lvds->pins) 524 + return -ENOMEM; 525 + 526 + lvds->pins->p = devm_pinctrl_get(lvds->dev); 527 + if (IS_ERR(lvds->pins->p)) { 528 + DRM_DEV_ERROR(dev, "no pinctrl handle\n"); 529 + devm_kfree(lvds->dev, lvds->pins); 530 + lvds->pins = NULL; 531 + } else { 532 + lvds->pins->default_state = 533 + pinctrl_lookup_state(lvds->pins->p, "lcdc"); 534 + if (IS_ERR(lvds->pins->default_state)) { 535 + DRM_DEV_ERROR(dev, "no default pinctrl state\n"); 536 + devm_kfree(lvds->dev, lvds->pins); 537 + lvds->pins = NULL; 538 + } 539 + } 540 + 541 + lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 542 + "rockchip,grf"); 543 + if (IS_ERR(lvds->grf)) { 544 + DRM_DEV_ERROR(dev, "missing rockchip,grf property\n"); 545 + return PTR_ERR(lvds->grf); 546 + } 547 + 548 + dev_set_drvdata(dev, lvds); 549 + 550 + ret = clk_prepare(lvds->pclk); 551 + if (ret < 0) { 552 + DRM_DEV_ERROR(dev, "failed to prepare pclk_lvds\n"); 553 + return ret; 554 + } 555 + ret = component_add(&pdev->dev, &rockchip_lvds_component_ops); 556 + if (ret < 0) { 557 + DRM_DEV_ERROR(dev, "failed to add component\n"); 558 + clk_unprepare(lvds->pclk); 559 + } 560 + 561 + return ret; 562 + } 563 + 564 + static int rockchip_lvds_remove(struct platform_device *pdev) 565 + { 566 + struct rockchip_lvds *lvds = dev_get_drvdata(&pdev->dev); 567 + 568 + component_del(&pdev->dev, &rockchip_lvds_component_ops); 569 + clk_unprepare(lvds->pclk); 570 + 571 + return 0; 572 + } 573 + 574 + struct platform_driver rockchip_lvds_driver = { 575 + .probe = rockchip_lvds_probe, 576 + .remove = rockchip_lvds_remove, 577 + .driver = { 578 + .name = "rockchip-lvds", 579 + .of_match_table = of_match_ptr(rockchip_lvds_dt_ids), 580 + }, 581 + };
+114
drivers/gpu/drm/rockchip/rockchip_lvds.h
··· 1 + /* 2 + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 + * Author: 4 + * Sandy Huang <hjc@rock-chips.com> 5 + * Mark Yao <mark.yao@rock-chips.com> 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #ifndef _ROCKCHIP_LVDS_ 18 + #define _ROCKCHIP_LVDS_ 19 + 20 + #define RK3288_LVDS_CH0_REG0 0x00 21 + #define RK3288_LVDS_CH0_REG0_LVDS_EN BIT(7) 22 + #define RK3288_LVDS_CH0_REG0_TTL_EN BIT(6) 23 + #define RK3288_LVDS_CH0_REG0_LANECK_EN BIT(5) 24 + #define RK3288_LVDS_CH0_REG0_LANE4_EN BIT(4) 25 + #define RK3288_LVDS_CH0_REG0_LANE3_EN BIT(3) 26 + #define RK3288_LVDS_CH0_REG0_LANE2_EN BIT(2) 27 + #define RK3288_LVDS_CH0_REG0_LANE1_EN BIT(1) 28 + #define RK3288_LVDS_CH0_REG0_LANE0_EN BIT(0) 29 + 30 + #define RK3288_LVDS_CH0_REG1 0x04 31 + #define RK3288_LVDS_CH0_REG1_LANECK_BIAS BIT(5) 32 + #define RK3288_LVDS_CH0_REG1_LANE4_BIAS BIT(4) 33 + #define RK3288_LVDS_CH0_REG1_LANE3_BIAS BIT(3) 34 + #define RK3288_LVDS_CH0_REG1_LANE2_BIAS BIT(2) 35 + #define RK3288_LVDS_CH0_REG1_LANE1_BIAS BIT(1) 36 + #define RK3288_LVDS_CH0_REG1_LANE0_BIAS BIT(0) 37 + 38 + #define RK3288_LVDS_CH0_REG2 0x08 39 + #define RK3288_LVDS_CH0_REG2_RESERVE_ON BIT(7) 40 + #define RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE BIT(6) 41 + #define RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE BIT(5) 42 + #define RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE BIT(4) 43 + #define RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE BIT(3) 44 + #define RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE BIT(2) 45 + #define RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE BIT(1) 46 + #define RK3288_LVDS_CH0_REG2_PLL_FBDIV8 BIT(0) 47 + 48 + #define RK3288_LVDS_CH0_REG3 0x0c 49 + #define RK3288_LVDS_CH0_REG3_PLL_FBDIV_MASK 0xff 50 + 51 + #define RK3288_LVDS_CH0_REG4 0x10 52 + #define RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE BIT(5) 53 + #define RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE BIT(4) 54 + #define RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE BIT(3) 55 + #define RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE BIT(2) 56 + #define RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE BIT(1) 57 + #define RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE BIT(0) 58 + 59 + #define RK3288_LVDS_CH0_REG5 0x14 60 + #define RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA BIT(5) 61 + #define RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA BIT(4) 62 + #define RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA BIT(3) 63 + #define RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA BIT(2) 64 + #define RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA BIT(1) 65 + #define RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA BIT(0) 66 + 67 + #define RK3288_LVDS_CFG_REGC 0x30 68 + #define RK3288_LVDS_CFG_REGC_PLL_ENABLE 0x00 69 + #define RK3288_LVDS_CFG_REGC_PLL_DISABLE 0xff 70 + 71 + #define RK3288_LVDS_CH0_REGD 0x34 72 + #define RK3288_LVDS_CH0_REGD_PLL_PREDIV_MASK 0x1f 73 + 74 + #define RK3288_LVDS_CH0_REG20 0x80 75 + #define RK3288_LVDS_CH0_REG20_MSB 0x45 76 + #define RK3288_LVDS_CH0_REG20_LSB 0x44 77 + 78 + #define RK3288_LVDS_CFG_REG21 0x84 79 + #define RK3288_LVDS_CFG_REG21_TX_ENABLE 0x92 80 + #define RK3288_LVDS_CFG_REG21_TX_DISABLE 0x00 81 + #define RK3288_LVDS_CH1_OFFSET 0x100 82 + 83 + /* fbdiv value is split over 2 registers, with bit8 in reg2 */ 84 + #define RK3288_LVDS_PLL_FBDIV_REG2(_fbd) \ 85 + (_fbd & BIT(8) ? RK3288_LVDS_CH0_REG2_PLL_FBDIV8 : 0) 86 + #define RK3288_LVDS_PLL_FBDIV_REG3(_fbd) \ 87 + (_fbd & RK3288_LVDS_CH0_REG3_PLL_FBDIV_MASK) 88 + #define RK3288_LVDS_PLL_PREDIV_REGD(_pd) \ 89 + (_pd & RK3288_LVDS_CH0_REGD_PLL_PREDIV_MASK) 90 + 91 + #define RK3288_LVDS_SOC_CON6_SEL_VOP_LIT BIT(3) 92 + 93 + #define LVDS_FMT_MASK (0x07 << 16) 94 + #define LVDS_MSB BIT(3) 95 + #define LVDS_DUAL BIT(4) 96 + #define LVDS_FMT_1 BIT(5) 97 + #define LVDS_TTL_EN BIT(6) 98 + #define LVDS_START_PHASE_RST_1 BIT(7) 99 + #define LVDS_DCLK_INV BIT(8) 100 + #define LVDS_CH0_EN BIT(11) 101 + #define LVDS_CH1_EN BIT(12) 102 + #define LVDS_PWRDN BIT(15) 103 + 104 + #define LVDS_24BIT (0 << 1) 105 + #define LVDS_18BIT (1 << 1) 106 + #define LVDS_FORMAT_VESA (0 << 0) 107 + #define LVDS_FORMAT_JEIDA (1 << 0) 108 + 109 + #define LVDS_VESA_24 0 110 + #define LVDS_JEIDA_24 1 111 + #define LVDS_VESA_18 2 112 + #define LVDS_JEIDA_18 3 113 + 114 + #endif /* _ROCKCHIP_LVDS_ */
+1 -1
drivers/gpu/drm/rockchip/rockchip_vop_reg.c
··· 533 533 struct device *dev = &pdev->dev; 534 534 535 535 if (!dev->of_node) { 536 - dev_err(dev, "can't find vop devices\n"); 536 + DRM_DEV_ERROR(dev, "can't find vop devices\n"); 537 537 return -ENODEV; 538 538 } 539 539
+2 -1
drivers/gpu/drm/sti/sti_drv.c
··· 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_crtc_helper.h> 18 18 #include <drm/drm_gem_cma_helper.h> 19 + #include <drm/drm_gem_framebuffer_helper.h> 19 20 #include <drm/drm_fb_cma_helper.h> 20 21 #include <drm/drm_of.h> 21 22 ··· 146 145 } 147 146 148 147 static const struct drm_mode_config_funcs sti_mode_config_funcs = { 149 - .fb_create = drm_fb_cma_create, 148 + .fb_create = drm_gem_fb_create, 150 149 .output_poll_changed = sti_output_poll_changed, 151 150 .atomic_check = sti_atomic_check, 152 151 .atomic_commit = drm_atomic_helper_commit,
+1 -5
drivers/gpu/drm/sti/sti_dvo.c
··· 463 463 bridge->driver_private = dvo; 464 464 bridge->funcs = &sti_dvo_bridge_funcs; 465 465 bridge->of_node = dvo->dev.of_node; 466 - err = drm_bridge_add(bridge); 467 - if (err) { 468 - DRM_ERROR("Failed to add bridge\n"); 469 - return err; 470 - } 466 + drm_bridge_add(bridge); 471 467 472 468 err = drm_bridge_attach(encoder, bridge, NULL); 473 469 if (err) {
+2 -1
drivers/gpu/drm/stm/drv.c
··· 17 17 #include <drm/drm_crtc_helper.h> 18 18 #include <drm/drm_fb_cma_helper.h> 19 19 #include <drm/drm_gem_cma_helper.h> 20 + #include <drm/drm_gem_framebuffer_helper.h> 20 21 21 22 #include "ltdc.h" 22 23 ··· 32 31 } 33 32 34 33 static const struct drm_mode_config_funcs drv_mode_config_funcs = { 35 - .fb_create = drm_fb_cma_create, 34 + .fb_create = drm_gem_fb_create, 36 35 .output_poll_changed = drv_output_poll_changed, 37 36 .atomic_check = drm_atomic_helper_check, 38 37 .atomic_commit = drm_atomic_helper_commit,
+6 -4
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
··· 113 113 114 114 static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf) 115 115 { 116 - /* prevent from division by 0 */ 117 - if (idf * odf) 118 - return DIV_ROUND_CLOSEST(clkin_khz * ndiv, idf * odf); 116 + int divisor = idf * odf; 119 117 120 - return 0; 118 + /* prevent from division by 0 */ 119 + if (!divisor) 120 + return 0; 121 + 122 + return DIV_ROUND_CLOSEST(clkin_khz * ndiv, divisor); 121 123 } 122 124 123 125 static int dsi_pll_get_params(int clkin_khz, int clkout_khz,
+77 -14
drivers/gpu/drm/sun4i/sun4i_drv.c
··· 106 106 goto free_drm; 107 107 } 108 108 109 - /* drm_vblank_init calls kcalloc, which can fail */ 110 - ret = drm_vblank_init(drm, 1); 111 - if (ret) 112 - goto free_mem_region; 113 - 114 109 drm_mode_config_init(drm); 115 110 116 111 ret = component_bind_all(drm->dev, drm); ··· 113 118 dev_err(drm->dev, "Couldn't bind all pipelines components\n"); 114 119 goto cleanup_mode_config; 115 120 } 121 + 122 + /* drm_vblank_init calls kcalloc, which can fail */ 123 + ret = drm_vblank_init(drm, drm->mode_config.num_crtc); 124 + if (ret) 125 + goto free_mem_region; 116 126 117 127 drm->irq_enabled = true; 118 128 ··· 200 200 return dev->of_node == data; 201 201 } 202 202 203 + /* 204 + * The encoder drivers use drm_of_find_possible_crtcs to get upstream 205 + * crtcs from the device tree using of_graph. For the results to be 206 + * correct, encoders must be probed/bound after _all_ crtcs have been 207 + * created. The existing code uses a depth first recursive traversal 208 + * of the of_graph, which means the encoders downstream of the TCON 209 + * get add right after the first TCON. The second TCON or CRTC will 210 + * never be properly associated with encoders connected to it. 211 + * 212 + * Also, in a dual display pipeline setup, both frontends can feed 213 + * either backend, and both backends can feed either TCON, we want 214 + * all components of the same type to be added before the next type 215 + * in the pipeline. Fortunately, the pipelines are perfectly symmetric, 216 + * i.e. components of the same type are at the same depth when counted 217 + * from the frontend. The only exception is the third pipeline in 218 + * the A80 SoC, which we do not support anyway. 219 + * 220 + * Hence we can use a breadth first search traversal order to add 221 + * components. We do not need to check for duplicates. The component 222 + * matching system handles this for us. 223 + */ 224 + struct endpoint_list { 225 + struct device_node *node; 226 + struct list_head list; 227 + }; 228 + 203 229 static int sun4i_drv_add_endpoints(struct device *dev, 230 + struct list_head *endpoints, 204 231 struct component_match **match, 205 232 struct device_node *node) 206 233 { 207 234 struct device_node *port, *ep, *remote; 235 + struct endpoint_list *endpoint; 208 236 int count = 0; 209 237 210 238 /* ··· 292 264 } 293 265 } 294 266 295 - /* Walk down our tree */ 296 - count += sun4i_drv_add_endpoints(dev, match, remote); 267 + /* Add downstream nodes to the queue */ 268 + endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); 269 + if (!endpoint) { 270 + of_node_put(remote); 271 + return -ENOMEM; 272 + } 297 273 298 - of_node_put(remote); 274 + endpoint->node = remote; 275 + list_add_tail(&endpoint->list, endpoints); 299 276 } 300 277 301 278 return count; ··· 310 277 { 311 278 struct component_match *match = NULL; 312 279 struct device_node *np = pdev->dev.of_node; 313 - int i, count = 0; 280 + struct endpoint_list *endpoint, *endpoint_temp; 281 + int i, ret, count = 0; 282 + LIST_HEAD(endpoints); 314 283 315 284 for (i = 0;; i++) { 316 285 struct device_node *pipeline = of_parse_phandle(np, ··· 321 286 if (!pipeline) 322 287 break; 323 288 324 - count += sun4i_drv_add_endpoints(&pdev->dev, &match, 325 - pipeline); 326 - of_node_put(pipeline); 289 + endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); 290 + if (!endpoint) { 291 + ret = -ENOMEM; 292 + goto err_free_endpoints; 293 + } 327 294 328 - DRM_DEBUG_DRIVER("Queued %d outputs on pipeline %d\n", 329 - count, i); 295 + endpoint->node = pipeline; 296 + list_add_tail(&endpoint->list, &endpoints); 297 + } 298 + 299 + list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) { 300 + /* process this endpoint */ 301 + ret = sun4i_drv_add_endpoints(&pdev->dev, &endpoints, &match, 302 + endpoint->node); 303 + 304 + /* sun4i_drv_add_endpoints can fail to allocate memory */ 305 + if (ret < 0) 306 + goto err_free_endpoints; 307 + 308 + count += ret; 309 + 310 + /* delete and cleanup the current entry */ 311 + list_del(&endpoint->list); 312 + of_node_put(endpoint->node); 313 + kfree(endpoint); 330 314 } 331 315 332 316 if (count) ··· 354 300 match); 355 301 else 356 302 return 0; 303 + 304 + err_free_endpoints: 305 + list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) { 306 + list_del(&endpoint->list); 307 + of_node_put(endpoint->node); 308 + kfree(endpoint); 309 + } 310 + 311 + return ret; 357 312 } 358 313 359 314 static int sun4i_drv_remove(struct platform_device *pdev)
+173 -27
drivers/gpu/drm/sun4i/sun4i_tcon.c
··· 463 463 * function in fact searches the corresponding engine, and the ID is 464 464 * requested via the get_id function of the engine. 465 465 */ 466 + static struct sunxi_engine * 467 + sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv, 468 + struct device_node *node) 469 + { 470 + struct device_node *port, *ep, *remote; 471 + struct sunxi_engine *engine = ERR_PTR(-EINVAL); 472 + 473 + port = of_graph_get_port_by_id(node, 0); 474 + if (!port) 475 + return ERR_PTR(-EINVAL); 476 + 477 + /* 478 + * This only works if there is only one path from the TCON 479 + * to any display engine. Otherwise the probe order of the 480 + * TCONs and display engines is not guaranteed. They may 481 + * either bind to the wrong one, or worse, bind to the same 482 + * one if additional checks are not done. 483 + * 484 + * Bail out if there are multiple input connections. 485 + */ 486 + if (of_get_available_child_count(port) != 1) 487 + goto out_put_port; 488 + 489 + /* Get the first connection without specifying an ID */ 490 + ep = of_get_next_available_child(port, NULL); 491 + if (!ep) 492 + goto out_put_port; 493 + 494 + remote = of_graph_get_remote_port_parent(ep); 495 + if (!remote) 496 + goto out_put_ep; 497 + 498 + /* does this node match any registered engines? */ 499 + list_for_each_entry(engine, &drv->engine_list, list) 500 + if (remote == engine->node) 501 + goto out_put_remote; 502 + 503 + /* keep looking through upstream ports */ 504 + engine = sun4i_tcon_find_engine_traverse(drv, remote); 505 + 506 + out_put_remote: 507 + of_node_put(remote); 508 + out_put_ep: 509 + of_node_put(ep); 510 + out_put_port: 511 + of_node_put(port); 512 + 513 + return engine; 514 + } 515 + 516 + /* 517 + * The device tree binding says that the remote endpoint ID of any 518 + * connection between components, up to and including the TCON, of 519 + * the display pipeline should be equal to the actual ID of the local 520 + * component. Thus we can look at any one of the input connections of 521 + * the TCONs, and use that connection's remote endpoint ID as our own. 522 + * 523 + * Since the user of this function already finds the input port, 524 + * the port is passed in directly without further checks. 525 + */ 526 + static int sun4i_tcon_of_get_id_from_port(struct device_node *port) 527 + { 528 + struct device_node *ep; 529 + int ret = -EINVAL; 530 + 531 + /* try finding an upstream endpoint */ 532 + for_each_available_child_of_node(port, ep) { 533 + struct device_node *remote; 534 + u32 reg; 535 + 536 + remote = of_graph_get_remote_endpoint(ep); 537 + if (!remote) 538 + continue; 539 + 540 + ret = of_property_read_u32(remote, "reg", &reg); 541 + if (ret) 542 + continue; 543 + 544 + ret = reg; 545 + } 546 + 547 + return ret; 548 + } 549 + 550 + /* 551 + * Once we know the TCON's id, we can look through the list of 552 + * engines to find a matching one. We assume all engines have 553 + * been probed and added to the list. 554 + */ 555 + static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv, 556 + int id) 557 + { 558 + struct sunxi_engine *engine; 559 + 560 + list_for_each_entry(engine, &drv->engine_list, list) 561 + if (engine->id == id) 562 + return engine; 563 + 564 + return ERR_PTR(-EINVAL); 565 + } 566 + 567 + /* 568 + * On SoCs with the old display pipeline design (Display Engine 1.0), 569 + * we assumed the TCON was always tied to just one backend. However 570 + * this proved not to be the case. On the A31, the TCON can select 571 + * either backend as its source. On the A20 (and likely on the A10), 572 + * the backend can choose which TCON to output to. 573 + * 574 + * The device tree binding says that the remote endpoint ID of any 575 + * connection between components, up to and including the TCON, of 576 + * the display pipeline should be equal to the actual ID of the local 577 + * component. Thus we should be able to look at any one of the input 578 + * connections of the TCONs, and use that connection's remote endpoint 579 + * ID as our own. 580 + * 581 + * However the connections between the backend and TCON were assumed 582 + * to be always singular, and their endpoit IDs were all incorrectly 583 + * set to 0. This means for these old device trees, we cannot just look 584 + * up the remote endpoint ID of a TCON input endpoint. TCON1 would be 585 + * incorrectly identified as TCON0. 586 + * 587 + * This function first checks if the TCON node has 2 input endpoints. 588 + * If so, then the device tree is a corrected version, and it will use 589 + * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above 590 + * to fetch the ID and engine directly. If not, then it is likely an 591 + * old device trees, where the endpoint IDs were incorrect, but did not 592 + * have endpoint connections between the backend and TCON across 593 + * different display pipelines. It will fall back to the old method of 594 + * traversing the of_graph to try and find a matching engine by device 595 + * node. 596 + * 597 + * In the case of single display pipeline device trees, either method 598 + * works. 599 + */ 466 600 static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, 467 601 struct device_node *node) 468 602 { 469 - struct device_node *port, *ep, *remote; 603 + struct device_node *port; 470 604 struct sunxi_engine *engine; 471 605 472 606 port = of_graph_get_port_by_id(node, 0); 473 607 if (!port) 474 608 return ERR_PTR(-EINVAL); 475 609 476 - for_each_available_child_of_node(port, ep) { 477 - remote = of_graph_get_remote_port_parent(ep); 478 - if (!remote) 479 - continue; 610 + /* 611 + * Is this a corrected device tree with cross pipeline 612 + * connections between the backend and TCON? 613 + */ 614 + if (of_get_child_count(port) > 1) { 615 + /* Get our ID directly from an upstream endpoint */ 616 + int id = sun4i_tcon_of_get_id_from_port(port); 480 617 481 - /* does this node match any registered engines? */ 482 - list_for_each_entry(engine, &drv->engine_list, list) { 483 - if (remote == engine->node) { 484 - of_node_put(remote); 485 - of_node_put(port); 486 - return engine; 487 - } 488 - } 618 + /* Get our engine by matching our ID */ 619 + engine = sun4i_tcon_get_engine_by_id(drv, id); 489 620 490 - /* keep looking through upstream ports */ 491 - engine = sun4i_tcon_find_engine(drv, remote); 492 - if (!IS_ERR(engine)) { 493 - of_node_put(remote); 494 - of_node_put(port); 495 - return engine; 496 - } 621 + of_node_put(port); 622 + return engine; 497 623 } 498 624 499 - return ERR_PTR(-EINVAL); 625 + /* Fallback to old method by traversing input endpoints */ 626 + of_node_put(port); 627 + return sun4i_tcon_find_engine_traverse(drv, node); 500 628 } 501 629 502 630 static int sun4i_tcon_bind(struct device *dev, struct device *master, ··· 658 530 } 659 531 660 532 /* Make sure our TCON is reset */ 661 - if (!reset_control_status(tcon->lcd_rst)) 662 - reset_control_assert(tcon->lcd_rst); 663 - 664 - ret = reset_control_deassert(tcon->lcd_rst); 533 + ret = reset_control_reset(tcon->lcd_rst); 665 534 if (ret) { 666 535 dev_err(dev, "Couldn't deassert our reset line\n"); 667 536 return ret; ··· 698 573 ret = sun4i_rgb_init(drm, tcon); 699 574 if (ret < 0) 700 575 goto err_free_clocks; 576 + 577 + if (tcon->quirks->needs_de_be_mux) { 578 + /* 579 + * We assume there is no dynamic muxing of backends 580 + * and TCONs, so we select the backend with same ID. 581 + * 582 + * While dynamic selection might be interesting, since 583 + * the CRTC is tied to the TCON, while the layers are 584 + * tied to the backends, this means, we will need to 585 + * switch between groups of layers. There might not be 586 + * a way to represent this constraint in DRM. 587 + */ 588 + regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 589 + SUN4I_TCON0_CTL_SRC_SEL_MASK, 590 + tcon->id); 591 + regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 592 + SUN4I_TCON1_CTL_SRC_SEL_MASK, 593 + tcon->id); 594 + } 701 595 702 596 list_add_tail(&tcon->list, &drv->tcon_list); 703 597 ··· 773 629 }; 774 630 775 631 static const struct sun4i_tcon_quirks sun6i_a31_quirks = { 776 - .has_channel_1 = true, 632 + .has_channel_1 = true, 633 + .needs_de_be_mux = true, 777 634 }; 778 635 779 636 static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { 780 - .has_channel_1 = true, 637 + .has_channel_1 = true, 638 + .needs_de_be_mux = true, 781 639 }; 782 640 783 641 static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
+3
drivers/gpu/drm/sun4i/sun4i_tcon.h
··· 37 37 #define SUN4I_TCON0_CTL_TCON_ENABLE BIT(31) 38 38 #define SUN4I_TCON0_CTL_CLK_DELAY_MASK GENMASK(8, 4) 39 39 #define SUN4I_TCON0_CTL_CLK_DELAY(delay) ((delay << 4) & SUN4I_TCON0_CTL_CLK_DELAY_MASK) 40 + #define SUN4I_TCON0_CTL_SRC_SEL_MASK GENMASK(2, 0) 40 41 41 42 #define SUN4I_TCON0_DCLK_REG 0x44 42 43 #define SUN4I_TCON0_DCLK_GATE_BIT (31) ··· 86 85 #define SUN4I_TCON1_CTL_INTERLACE_ENABLE BIT(20) 87 86 #define SUN4I_TCON1_CTL_CLK_DELAY_MASK GENMASK(8, 4) 88 87 #define SUN4I_TCON1_CTL_CLK_DELAY(delay) ((delay << 4) & SUN4I_TCON1_CTL_CLK_DELAY_MASK) 88 + #define SUN4I_TCON1_CTL_SRC_SEL_MASK GENMASK(1, 0) 89 89 90 90 #define SUN4I_TCON1_BASIC0_REG 0x94 91 91 #define SUN4I_TCON1_BASIC0_X(width) ((((width) - 1) & 0xfff) << 16) ··· 148 146 struct sun4i_tcon_quirks { 149 147 bool has_unknown_mux; /* sun5i has undocumented mux */ 150 148 bool has_channel_1; /* a33 does not have channel 1 */ 149 + bool needs_de_be_mux; /* sun6i needs mux to select backend */ 151 150 }; 152 151 153 152 struct sun4i_tcon {
+2 -1
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 23 23 #include <drm/drm_atomic.h> 24 24 #include <drm/drm_atomic_helper.h> 25 25 #include <drm/drm_fb_helper.h> 26 + #include <drm/drm_gem_framebuffer_helper.h> 26 27 27 28 #include "tilcdc_drv.h" 28 29 #include "tilcdc_regs.h" ··· 66 65 static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev, 67 66 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) 68 67 { 69 - return drm_fb_cma_create(dev, file_priv, mode_cmd); 68 + return drm_gem_fb_create(dev, file_priv, mode_cmd); 70 69 } 71 70 72 71 static void tilcdc_fb_output_poll_changed(struct drm_device *dev)
+1 -13
drivers/gpu/drm/tinydrm/mi0283qt.c
··· 163 163 static int mi0283qt_probe(struct spi_device *spi) 164 164 { 165 165 struct device *dev = &spi->dev; 166 - struct tinydrm_device *tdev; 167 166 struct mipi_dbi *mipi; 168 167 struct gpio_desc *dc; 169 168 u32 rotation = 0; ··· 214 215 return ret; 215 216 } 216 217 217 - tdev = &mipi->tinydrm; 218 - 219 - ret = devm_tinydrm_register(tdev); 220 - if (ret) 221 - return ret; 222 - 223 218 spi_set_drvdata(spi, mipi); 224 219 225 - DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", 226 - tdev->drm->driver->name, dev_name(dev), 227 - spi->max_speed_hz / 1000000, 228 - tdev->drm->primary->index); 229 - 230 - return 0; 220 + return devm_tinydrm_register(&mipi->tinydrm); 231 221 } 232 222 233 223 static void mi0283qt_shutdown(struct spi_device *spi)
+2
drivers/gpu/drm/tinydrm/mipi-dbi.c
··· 842 842 return -ENOMEM; 843 843 } 844 844 845 + DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000); 846 + 845 847 return 0; 846 848 } 847 849 EXPORT_SYMBOL(mipi_dbi_spi_init);
+2 -10
drivers/gpu/drm/tinydrm/repaper.c
··· 1078 1078 return ret; 1079 1079 1080 1080 drm_mode_config_reset(tdev->drm); 1081 - 1082 - ret = devm_tinydrm_register(tdev); 1083 - if (ret) 1084 - return ret; 1085 - 1086 1081 spi_set_drvdata(spi, tdev); 1087 1082 1088 - DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", 1089 - tdev->drm->driver->name, dev_name(dev), 1090 - spi->max_speed_hz / 1000000, 1091 - tdev->drm->primary->index); 1083 + DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000); 1092 1084 1093 - return 0; 1085 + return devm_tinydrm_register(tdev); 1094 1086 } 1095 1087 1096 1088 static void repaper_shutdown(struct spi_device *spi)
+1 -13
drivers/gpu/drm/tinydrm/st7586.c
··· 343 343 static int st7586_probe(struct spi_device *spi) 344 344 { 345 345 struct device *dev = &spi->dev; 346 - struct tinydrm_device *tdev; 347 346 struct mipi_dbi *mipi; 348 347 struct gpio_desc *a0; 349 348 u32 rotation = 0; ··· 387 388 if (ret) 388 389 return ret; 389 390 390 - tdev = &mipi->tinydrm; 391 - 392 - ret = devm_tinydrm_register(tdev); 393 - if (ret) 394 - return ret; 395 - 396 391 spi_set_drvdata(spi, mipi); 397 392 398 - DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", 399 - tdev->drm->driver->name, dev_name(dev), 400 - spi->max_speed_hz / 1000000, 401 - tdev->drm->primary->index); 402 - 403 - return 0; 393 + return devm_tinydrm_register(&mipi->tinydrm); 404 394 } 405 395 406 396 static void st7586_shutdown(struct spi_device *spi)
+16
drivers/gpu/drm/tve200/Kconfig
··· 1 + config DRM_TVE200 2 + tristate "DRM Support for Faraday TV Encoder TVE200" 3 + depends on DRM 4 + depends on CMA 5 + depends on ARM || COMPILE_TEST 6 + depends on OF 7 + select DRM_BRIDGE 8 + select DRM_PANEL_BRIDGE 9 + select DRM_KMS_HELPER 10 + select DRM_KMS_CMA_HELPER 11 + select DRM_GEM_CMA_HELPER 12 + select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE 13 + help 14 + Choose this option for DRM support for the Faraday TV Encoder 15 + TVE200 Controller. 16 + If M is selected the module will be called tve200_drm.
+4
drivers/gpu/drm/tve200/Makefile
··· 1 + tve200_drm-y += tve200_display.o \ 2 + tve200_drv.o 3 + 4 + obj-$(CONFIG_DRM_TVE200) += tve200_drm.o
+337
drivers/gpu/drm/tve200/tve200_display.c
··· 1 + /* 2 + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> 3 + * Parts of this file were based on sources as follows: 4 + * 5 + * Copyright (C) 2006-2008 Intel Corporation 6 + * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com> 7 + * Copyright (C) 2007 Dave Airlie <airlied@linux.ie> 8 + * Copyright (C) 2011 Texas Instruments 9 + * Copyright (C) 2017 Eric Anholt 10 + * 11 + * This program is free software and is provided to you under the terms of the 12 + * GNU General Public License version 2 as published by the Free Software 13 + * Foundation, and any use by you of this program is subject to the terms of 14 + * such GNU licence. 15 + */ 16 + #include <linux/clk.h> 17 + #include <linux/version.h> 18 + #include <linux/dma-buf.h> 19 + #include <linux/of_graph.h> 20 + 21 + #include <drm/drmP.h> 22 + #include <drm/drm_panel.h> 23 + #include <drm/drm_gem_cma_helper.h> 24 + #include <drm/drm_fb_cma_helper.h> 25 + 26 + #include "tve200_drm.h" 27 + 28 + irqreturn_t tve200_irq(int irq, void *data) 29 + { 30 + struct tve200_drm_dev_private *priv = data; 31 + u32 stat; 32 + u32 val; 33 + 34 + stat = readl(priv->regs + TVE200_INT_STAT); 35 + 36 + if (!stat) 37 + return IRQ_NONE; 38 + 39 + /* 40 + * Vblank IRQ 41 + * 42 + * The hardware is a bit tilted: the line stays high after clearing 43 + * the vblank IRQ, firing many more interrupts. We counter this 44 + * by toggling the IRQ back and forth from firing at vblank and 45 + * firing at start of active image, which works around the problem 46 + * since those occur strictly in sequence, and we get two IRQs for each 47 + * frame, one at start of Vblank (that we make call into the CRTC) and 48 + * another one at the start of the image (that we discard). 49 + */ 50 + if (stat & TVE200_INT_V_STATUS) { 51 + val = readl(priv->regs + TVE200_CTRL); 52 + /* We have an actual start of vsync */ 53 + if (!(val & TVE200_VSTSTYPE_BITS)) { 54 + drm_crtc_handle_vblank(&priv->pipe.crtc); 55 + /* Toggle trigger to start of active image */ 56 + val |= TVE200_VSTSTYPE_VAI; 57 + } else { 58 + /* Toggle trigger back to start of vsync */ 59 + val &= ~TVE200_VSTSTYPE_BITS; 60 + } 61 + writel(val, priv->regs + TVE200_CTRL); 62 + } else 63 + dev_err(priv->drm->dev, "stray IRQ %08x\n", stat); 64 + 65 + /* Clear the interrupt once done */ 66 + writel(stat, priv->regs + TVE200_INT_CLR); 67 + 68 + return IRQ_HANDLED; 69 + } 70 + 71 + static int tve200_display_check(struct drm_simple_display_pipe *pipe, 72 + struct drm_plane_state *pstate, 73 + struct drm_crtc_state *cstate) 74 + { 75 + const struct drm_display_mode *mode = &cstate->mode; 76 + struct drm_framebuffer *old_fb = pipe->plane.state->fb; 77 + struct drm_framebuffer *fb = pstate->fb; 78 + 79 + /* 80 + * We support these specific resolutions and nothing else. 81 + */ 82 + if (!(mode->hdisplay == 352 && mode->vdisplay == 240) && /* SIF(525) */ 83 + !(mode->hdisplay == 352 && mode->vdisplay == 288) && /* CIF(625) */ 84 + !(mode->hdisplay == 640 && mode->vdisplay == 480) && /* VGA */ 85 + !(mode->hdisplay == 720 && mode->vdisplay == 480) && /* D1 */ 86 + !(mode->hdisplay == 720 && mode->vdisplay == 576)) { /* D1 */ 87 + DRM_DEBUG_KMS("unsupported display mode (%u x %u)\n", 88 + mode->hdisplay, mode->vdisplay); 89 + return -EINVAL; 90 + } 91 + 92 + if (fb) { 93 + u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0); 94 + 95 + /* FB base address must be dword aligned. */ 96 + if (offset & 3) { 97 + DRM_DEBUG_KMS("FB not 32-bit aligned\n"); 98 + return -EINVAL; 99 + } 100 + 101 + /* 102 + * There's no pitch register, the mode's hdisplay 103 + * controls this. 104 + */ 105 + if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) { 106 + DRM_DEBUG_KMS("can't handle pitches\n"); 107 + return -EINVAL; 108 + } 109 + 110 + /* 111 + * We can't change the FB format in a flicker-free 112 + * manner (and only update it during CRTC enable). 113 + */ 114 + if (old_fb && old_fb->format != fb->format) 115 + cstate->mode_changed = true; 116 + } 117 + 118 + return 0; 119 + } 120 + 121 + static void tve200_display_enable(struct drm_simple_display_pipe *pipe, 122 + struct drm_crtc_state *cstate) 123 + { 124 + struct drm_crtc *crtc = &pipe->crtc; 125 + struct drm_plane *plane = &pipe->plane; 126 + struct drm_device *drm = crtc->dev; 127 + struct tve200_drm_dev_private *priv = drm->dev_private; 128 + const struct drm_display_mode *mode = &cstate->mode; 129 + struct drm_framebuffer *fb = plane->state->fb; 130 + struct drm_connector *connector = priv->connector; 131 + u32 format = fb->format->format; 132 + u32 ctrl1 = 0; 133 + 134 + clk_prepare_enable(priv->clk); 135 + 136 + /* Function 1 */ 137 + ctrl1 |= TVE200_CTRL_CSMODE; 138 + /* Interlace mode for CCIR656: parameterize? */ 139 + ctrl1 |= TVE200_CTRL_NONINTERLACE; 140 + /* 32 words per burst */ 141 + ctrl1 |= TVE200_CTRL_BURST_32_WORDS; 142 + /* 16 retries */ 143 + ctrl1 |= TVE200_CTRL_RETRYCNT_16; 144 + /* NTSC mode: parametrize? */ 145 + ctrl1 |= TVE200_CTRL_NTSC; 146 + 147 + /* Vsync IRQ at start of Vsync at first */ 148 + ctrl1 |= TVE200_VSTSTYPE_VSYNC; 149 + 150 + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE) 151 + ctrl1 |= TVE200_CTRL_TVCLKP; 152 + 153 + if ((mode->hdisplay == 352 && mode->vdisplay == 240) || /* SIF(525) */ 154 + (mode->hdisplay == 352 && mode->vdisplay == 288)) { /* CIF(625) */ 155 + ctrl1 |= TVE200_CTRL_IPRESOL_CIF; 156 + dev_info(drm->dev, "CIF mode\n"); 157 + } else if (mode->hdisplay == 640 && mode->vdisplay == 480) { 158 + ctrl1 |= TVE200_CTRL_IPRESOL_VGA; 159 + dev_info(drm->dev, "VGA mode\n"); 160 + } else if ((mode->hdisplay == 720 && mode->vdisplay == 480) || 161 + (mode->hdisplay == 720 && mode->vdisplay == 576)) { 162 + ctrl1 |= TVE200_CTRL_IPRESOL_D1; 163 + dev_info(drm->dev, "D1 mode\n"); 164 + } 165 + 166 + if (format & DRM_FORMAT_BIG_ENDIAN) { 167 + ctrl1 |= TVE200_CTRL_BBBP; 168 + format &= ~DRM_FORMAT_BIG_ENDIAN; 169 + } 170 + 171 + switch (format) { 172 + case DRM_FORMAT_XRGB8888: 173 + ctrl1 |= TVE200_IPDMOD_RGB888; 174 + break; 175 + case DRM_FORMAT_RGB565: 176 + ctrl1 |= TVE200_IPDMOD_RGB565; 177 + break; 178 + case DRM_FORMAT_XRGB1555: 179 + ctrl1 |= TVE200_IPDMOD_RGB555; 180 + break; 181 + case DRM_FORMAT_XBGR8888: 182 + ctrl1 |= TVE200_IPDMOD_RGB888 | TVE200_BGR; 183 + break; 184 + case DRM_FORMAT_BGR565: 185 + ctrl1 |= TVE200_IPDMOD_RGB565 | TVE200_BGR; 186 + break; 187 + case DRM_FORMAT_XBGR1555: 188 + ctrl1 |= TVE200_IPDMOD_RGB555 | TVE200_BGR; 189 + break; 190 + case DRM_FORMAT_YUYV: 191 + ctrl1 |= TVE200_IPDMOD_YUV422; 192 + ctrl1 |= TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0; 193 + break; 194 + case DRM_FORMAT_YVYU: 195 + ctrl1 |= TVE200_IPDMOD_YUV422; 196 + ctrl1 |= TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0; 197 + break; 198 + case DRM_FORMAT_UYVY: 199 + ctrl1 |= TVE200_IPDMOD_YUV422; 200 + ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0; 201 + break; 202 + case DRM_FORMAT_VYUY: 203 + ctrl1 |= TVE200_IPDMOD_YUV422; 204 + ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0; 205 + break; 206 + case DRM_FORMAT_YUV420: 207 + ctrl1 |= TVE200_CTRL_YUV420; 208 + ctrl1 |= TVE200_IPDMOD_YUV420; 209 + break; 210 + default: 211 + dev_err(drm->dev, "Unknown FB format 0x%08x\n", 212 + fb->format->format); 213 + break; 214 + } 215 + 216 + ctrl1 |= TVE200_TVEEN; 217 + 218 + /* Turn it on */ 219 + writel(ctrl1, priv->regs + TVE200_CTRL); 220 + 221 + drm_crtc_vblank_on(crtc); 222 + } 223 + 224 + void tve200_display_disable(struct drm_simple_display_pipe *pipe) 225 + { 226 + struct drm_crtc *crtc = &pipe->crtc; 227 + struct drm_device *drm = crtc->dev; 228 + struct tve200_drm_dev_private *priv = drm->dev_private; 229 + 230 + drm_crtc_vblank_off(crtc); 231 + 232 + /* Disable and Power Down */ 233 + writel(0, priv->regs + TVE200_CTRL); 234 + 235 + clk_disable_unprepare(priv->clk); 236 + } 237 + 238 + static void tve200_display_update(struct drm_simple_display_pipe *pipe, 239 + struct drm_plane_state *old_pstate) 240 + { 241 + struct drm_crtc *crtc = &pipe->crtc; 242 + struct drm_device *drm = crtc->dev; 243 + struct tve200_drm_dev_private *priv = drm->dev_private; 244 + struct drm_pending_vblank_event *event = crtc->state->event; 245 + struct drm_plane *plane = &pipe->plane; 246 + struct drm_plane_state *pstate = plane->state; 247 + struct drm_framebuffer *fb = pstate->fb; 248 + 249 + if (fb) { 250 + /* For RGB, the Y component is used as base address */ 251 + writel(drm_fb_cma_get_gem_addr(fb, pstate, 0), 252 + priv->regs + TVE200_Y_FRAME_BASE_ADDR); 253 + 254 + /* For three plane YUV we need two more addresses */ 255 + if (fb->format->format == DRM_FORMAT_YUV420) { 256 + writel(drm_fb_cma_get_gem_addr(fb, pstate, 1), 257 + priv->regs + TVE200_U_FRAME_BASE_ADDR); 258 + writel(drm_fb_cma_get_gem_addr(fb, pstate, 2), 259 + priv->regs + TVE200_V_FRAME_BASE_ADDR); 260 + } 261 + } 262 + 263 + if (event) { 264 + crtc->state->event = NULL; 265 + 266 + spin_lock_irq(&crtc->dev->event_lock); 267 + if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) 268 + drm_crtc_arm_vblank_event(crtc, event); 269 + else 270 + drm_crtc_send_vblank_event(crtc, event); 271 + spin_unlock_irq(&crtc->dev->event_lock); 272 + } 273 + } 274 + 275 + int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc) 276 + { 277 + struct tve200_drm_dev_private *priv = drm->dev_private; 278 + 279 + writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN); 280 + return 0; 281 + } 282 + 283 + void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc) 284 + { 285 + struct tve200_drm_dev_private *priv = drm->dev_private; 286 + 287 + writel(0, priv->regs + TVE200_INT_EN); 288 + } 289 + 290 + static int tve200_display_prepare_fb(struct drm_simple_display_pipe *pipe, 291 + struct drm_plane_state *plane_state) 292 + { 293 + return drm_fb_cma_prepare_fb(&pipe->plane, plane_state); 294 + } 295 + 296 + const struct drm_simple_display_pipe_funcs tve200_display_funcs = { 297 + .check = tve200_display_check, 298 + .enable = tve200_display_enable, 299 + .disable = tve200_display_disable, 300 + .update = tve200_display_update, 301 + .prepare_fb = tve200_display_prepare_fb, 302 + }; 303 + 304 + int tve200_display_init(struct drm_device *drm) 305 + { 306 + struct tve200_drm_dev_private *priv = drm->dev_private; 307 + int ret; 308 + static const u32 formats[] = { 309 + DRM_FORMAT_XRGB8888, 310 + DRM_FORMAT_XBGR8888, 311 + DRM_FORMAT_RGB565, 312 + DRM_FORMAT_BGR565, 313 + DRM_FORMAT_XRGB1555, 314 + DRM_FORMAT_XBGR1555, 315 + /* 316 + * The controller actually supports any YCbCr ordering, 317 + * for packed YCbCr. This just lists the orderings that 318 + * DRM supports. 319 + */ 320 + DRM_FORMAT_YUYV, 321 + DRM_FORMAT_YVYU, 322 + DRM_FORMAT_UYVY, 323 + DRM_FORMAT_VYUY, 324 + /* This uses three planes */ 325 + DRM_FORMAT_YUV420, 326 + }; 327 + 328 + ret = drm_simple_display_pipe_init(drm, &priv->pipe, 329 + &tve200_display_funcs, 330 + formats, ARRAY_SIZE(formats), 331 + NULL, 332 + priv->connector); 333 + if (ret) 334 + return ret; 335 + 336 + return 0; 337 + }
+126
drivers/gpu/drm/tve200/tve200_drm.h
··· 1 + /* 2 + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> 3 + * Parts of this file were based on sources as follows: 4 + * 5 + * Copyright (C) 2006-2008 Intel Corporation 6 + * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com> 7 + * Copyright (C) 2007 Dave Airlie <airlied@linux.ie> 8 + * Copyright (C) 2011 Texas Instruments 9 + * Copyright (C) 2017 Eric Anholt 10 + * 11 + * This program is free software and is provided to you under the terms of the 12 + * GNU General Public License version 2 as published by the Free Software 13 + * Foundation, and any use by you of this program is subject to the terms of 14 + * such GNU licence. 15 + */ 16 + 17 + #ifndef _TVE200_DRM_H_ 18 + #define _TVE200_DRM_H_ 19 + 20 + /* Bits 2-31 are valid physical base addresses */ 21 + #define TVE200_Y_FRAME_BASE_ADDR 0x00 22 + #define TVE200_U_FRAME_BASE_ADDR 0x04 23 + #define TVE200_V_FRAME_BASE_ADDR 0x08 24 + 25 + #define TVE200_INT_EN 0x0C 26 + #define TVE200_INT_CLR 0x10 27 + #define TVE200_INT_STAT 0x14 28 + #define TVE200_INT_BUS_ERR BIT(7) 29 + #define TVE200_INT_V_STATUS BIT(6) /* vertical blank */ 30 + #define TVE200_INT_V_NEXT_FRAME BIT(5) 31 + #define TVE200_INT_U_NEXT_FRAME BIT(4) 32 + #define TVE200_INT_Y_NEXT_FRAME BIT(3) 33 + #define TVE200_INT_V_FIFO_UNDERRUN BIT(2) 34 + #define TVE200_INT_U_FIFO_UNDERRUN BIT(1) 35 + #define TVE200_INT_Y_FIFO_UNDERRUN BIT(0) 36 + #define TVE200_FIFO_UNDERRUNS (TVE200_INT_V_FIFO_UNDERRUN | \ 37 + TVE200_INT_U_FIFO_UNDERRUN | \ 38 + TVE200_INT_Y_FIFO_UNDERRUN) 39 + 40 + #define TVE200_CTRL 0x18 41 + #define TVE200_CTRL_YUV420 BIT(31) 42 + #define TVE200_CTRL_CSMODE BIT(30) 43 + #define TVE200_CTRL_NONINTERLACE BIT(28) /* 0 = non-interlace CCIR656 */ 44 + #define TVE200_CTRL_TVCLKP BIT(27) /* Inverted clock phase */ 45 + /* Bits 24..26 define the burst size after arbitration on the bus */ 46 + #define TVE200_CTRL_BURST_4_WORDS (0 << 24) 47 + #define TVE200_CTRL_BURST_8_WORDS (1 << 24) 48 + #define TVE200_CTRL_BURST_16_WORDS (2 << 24) 49 + #define TVE200_CTRL_BURST_32_WORDS (3 << 24) 50 + #define TVE200_CTRL_BURST_64_WORDS (4 << 24) 51 + #define TVE200_CTRL_BURST_128_WORDS (5 << 24) 52 + #define TVE200_CTRL_BURST_256_WORDS (6 << 24) 53 + #define TVE200_CTRL_BURST_0_WORDS (7 << 24) /* ? */ 54 + /* 55 + * Bits 16..23 is the retry count*16 before issueing a new AHB transfer 56 + * on the AHB bus. 57 + */ 58 + #define TVE200_CTRL_RETRYCNT_MASK GENMASK(23, 16) 59 + #define TVE200_CTRL_RETRYCNT_16 (1 << 16) 60 + #define TVE200_CTRL_BBBP BIT(15) /* 0 = little-endian */ 61 + /* Bits 12..14 define the YCbCr ordering */ 62 + #define TVE200_CTRL_YCBCRODR_CB0Y0CR0Y1 (0 << 12) 63 + #define TVE200_CTRL_YCBCRODR_Y0CB0Y1CR0 (1 << 12) 64 + #define TVE200_CTRL_YCBCRODR_CR0Y0CB0Y1 (2 << 12) 65 + #define TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0 (3 << 12) 66 + #define TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0 (4 << 12) 67 + #define TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0 (5 << 12) 68 + #define TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0 (6 << 12) 69 + #define TVE200_CTRL_YCBCRODR_Y0CR0Y1CB0 (7 << 12) 70 + /* Bits 10..11 define the input resolution (framebuffer size) */ 71 + #define TVE200_CTRL_IPRESOL_CIF (0 << 10) 72 + #define TVE200_CTRL_IPRESOL_VGA (1 << 10) 73 + #define TVE200_CTRL_IPRESOL_D1 (2 << 10) 74 + #define TVE200_CTRL_NTSC BIT(9) /* 0 = PAL, 1 = NTSC */ 75 + #define TVE200_CTRL_INTERLACE BIT(8) /* 1 = interlace, only for D1 */ 76 + #define TVE200_IPDMOD_RGB555 (0 << 6) /* TVE200_CTRL_YUV420 = 0 */ 77 + #define TVE200_IPDMOD_RGB565 (1 << 6) 78 + #define TVE200_IPDMOD_RGB888 (2 << 6) 79 + #define TVE200_IPDMOD_YUV420 (2 << 6) /* TVE200_CTRL_YUV420 = 1 */ 80 + #define TVE200_IPDMOD_YUV422 (3 << 6) 81 + /* Bits 4 & 5 define when to fire the vblank IRQ */ 82 + #define TVE200_VSTSTYPE_VSYNC (0 << 4) /* start of vsync */ 83 + #define TVE200_VSTSTYPE_VBP (1 << 4) /* start of v back porch */ 84 + #define TVE200_VSTSTYPE_VAI (2 << 4) /* start of v active image */ 85 + #define TVE200_VSTSTYPE_VFP (3 << 4) /* start of v front porch */ 86 + #define TVE200_VSTSTYPE_BITS (BIT(4) | BIT(5)) 87 + #define TVE200_BGR BIT(1) /* 0 = RGB, 1 = BGR */ 88 + #define TVE200_TVEEN BIT(0) /* Enable TVE block */ 89 + 90 + #define TVE200_CTRL_2 0x1c 91 + #define TVE200_CTRL_3 0x20 92 + 93 + #define TVE200_CTRL_4 0x24 94 + #define TVE200_CTRL_4_RESET BIT(0) /* triggers reset of TVE200 */ 95 + 96 + #include <drm/drm_gem.h> 97 + #include <drm/drm_simple_kms_helper.h> 98 + 99 + struct tve200_drm_dev_private { 100 + struct drm_device *drm; 101 + 102 + struct drm_connector *connector; 103 + struct drm_panel *panel; 104 + struct drm_bridge *bridge; 105 + struct drm_simple_display_pipe pipe; 106 + struct drm_fbdev_cma *fbdev; 107 + 108 + void *regs; 109 + struct clk *pclk; 110 + struct clk *clk; 111 + }; 112 + 113 + #define to_tve200_connector(x) \ 114 + container_of(x, struct tve200_drm_connector, connector) 115 + 116 + int tve200_display_init(struct drm_device *dev); 117 + int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc); 118 + void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc); 119 + irqreturn_t tve200_irq(int irq, void *data); 120 + int tve200_connector_init(struct drm_device *dev); 121 + int tve200_encoder_init(struct drm_device *dev); 122 + int tve200_dumb_create(struct drm_file *file_priv, 123 + struct drm_device *dev, 124 + struct drm_mode_create_dumb *args); 125 + 126 + #endif /* _TVE200_DRM_H_ */
+302
drivers/gpu/drm/tve200/tve200_drv.c
··· 1 + /* 2 + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> 3 + * Parts of this file were based on sources as follows: 4 + * 5 + * Copyright (C) 2006-2008 Intel Corporation 6 + * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com> 7 + * Copyright (C) 2007 Dave Airlie <airlied@linux.ie> 8 + * Copyright (C) 2011 Texas Instruments 9 + * Copyright (C) 2017 Eric Anholt 10 + * 11 + * This program is free software and is provided to you under the terms of the 12 + * GNU General Public License version 2 as published by the Free Software 13 + * Foundation, and any use by you of this program is subject to the terms of 14 + * such GNU licence. 15 + */ 16 + 17 + /** 18 + * DOC: Faraday TV Encoder TVE200 DRM Driver 19 + * 20 + * The Faraday TV Encoder TVE200 is also known as the Gemini TV Interface 21 + * Controller (TVC) and is found in the Gemini Chipset from Storlink 22 + * Semiconductor (later Storm Semiconductor, later Cortina Systems) 23 + * but also in the Grain Media GM8180 chipset. On the Gemini the module 24 + * is connected to 8 data lines and a single clock line, comprising an 25 + * 8-bit BT.656 interface. 26 + * 27 + * This is a very basic YUV display driver. The datasheet specifies that 28 + * it supports the ITU BT.656 standard. It requires a 27 MHz clock which is 29 + * the hallmark of any TV encoder supporting both PAL and NTSC. 30 + * 31 + * This driver exposes a standard KMS interface for this TV encoder. 32 + */ 33 + 34 + #include <linux/clk.h> 35 + #include <linux/dma-buf.h> 36 + #include <linux/irq.h> 37 + #include <linux/io.h> 38 + #include <linux/module.h> 39 + #include <linux/platform_device.h> 40 + #include <linux/shmem_fs.h> 41 + #include <linux/slab.h> 42 + #include <linux/version.h> 43 + 44 + #include <drm/drmP.h> 45 + #include <drm/drm_atomic_helper.h> 46 + #include <drm/drm_crtc_helper.h> 47 + #include <drm/drm_gem_cma_helper.h> 48 + #include <drm/drm_fb_cma_helper.h> 49 + #include <drm/drm_panel.h> 50 + #include <drm/drm_of.h> 51 + #include <drm/drm_bridge.h> 52 + 53 + #include "tve200_drm.h" 54 + 55 + #define DRIVER_DESC "DRM module for Faraday TVE200" 56 + 57 + static const struct drm_mode_config_funcs mode_config_funcs = { 58 + .fb_create = drm_fb_cma_create, 59 + .atomic_check = drm_atomic_helper_check, 60 + .atomic_commit = drm_atomic_helper_commit, 61 + }; 62 + 63 + static int tve200_modeset_init(struct drm_device *dev) 64 + { 65 + struct drm_mode_config *mode_config; 66 + struct tve200_drm_dev_private *priv = dev->dev_private; 67 + struct drm_panel *panel; 68 + struct drm_bridge *bridge; 69 + int ret = 0; 70 + 71 + drm_mode_config_init(dev); 72 + mode_config = &dev->mode_config; 73 + mode_config->funcs = &mode_config_funcs; 74 + mode_config->min_width = 352; 75 + mode_config->max_width = 720; 76 + mode_config->min_height = 240; 77 + mode_config->max_height = 576; 78 + 79 + ret = drm_of_find_panel_or_bridge(dev->dev->of_node, 80 + 0, 0, &panel, &bridge); 81 + if (ret && ret != -ENODEV) 82 + return ret; 83 + if (panel) { 84 + bridge = drm_panel_bridge_add(panel, 85 + DRM_MODE_CONNECTOR_Unknown); 86 + if (IS_ERR(bridge)) { 87 + ret = PTR_ERR(bridge); 88 + goto out_bridge; 89 + } 90 + } else { 91 + /* 92 + * TODO: when we are using a different bridge than a panel 93 + * (such as a dumb VGA connector) we need to devise a different 94 + * method to get the connector out of the bridge. 95 + */ 96 + dev_err(dev->dev, "the bridge is not a panel\n"); 97 + goto out_bridge; 98 + } 99 + 100 + ret = tve200_display_init(dev); 101 + if (ret) { 102 + dev_err(dev->dev, "failed to init display\n"); 103 + goto out_bridge; 104 + } 105 + 106 + ret = drm_simple_display_pipe_attach_bridge(&priv->pipe, 107 + bridge); 108 + if (ret) { 109 + dev_err(dev->dev, "failed to attach bridge\n"); 110 + goto out_bridge; 111 + } 112 + 113 + priv->panel = panel; 114 + priv->connector = panel->connector; 115 + priv->bridge = bridge; 116 + 117 + dev_info(dev->dev, "attached to panel %s\n", 118 + dev_name(panel->dev)); 119 + 120 + ret = drm_vblank_init(dev, 1); 121 + if (ret) { 122 + dev_err(dev->dev, "failed to init vblank\n"); 123 + goto out_bridge; 124 + } 125 + 126 + drm_mode_config_reset(dev); 127 + 128 + /* 129 + * Passing in 16 here will make the RGB656 mode the default 130 + * Passing in 32 will use XRGB8888 mode 131 + */ 132 + priv->fbdev = drm_fbdev_cma_init(dev, 16, 133 + dev->mode_config.num_connector); 134 + drm_kms_helper_poll_init(dev); 135 + 136 + goto finish; 137 + 138 + out_bridge: 139 + if (panel) 140 + drm_panel_bridge_remove(bridge); 141 + drm_mode_config_cleanup(dev); 142 + finish: 143 + return ret; 144 + } 145 + 146 + DEFINE_DRM_GEM_CMA_FOPS(drm_fops); 147 + 148 + static void tve200_lastclose(struct drm_device *dev) 149 + { 150 + struct tve200_drm_dev_private *priv = dev->dev_private; 151 + 152 + drm_fbdev_cma_restore_mode(priv->fbdev); 153 + } 154 + 155 + static struct drm_driver tve200_drm_driver = { 156 + .driver_features = 157 + DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, 158 + .lastclose = tve200_lastclose, 159 + .ioctls = NULL, 160 + .fops = &drm_fops, 161 + .name = "tve200", 162 + .desc = DRIVER_DESC, 163 + .date = "20170703", 164 + .major = 1, 165 + .minor = 0, 166 + .patchlevel = 0, 167 + .dumb_create = drm_gem_cma_dumb_create, 168 + .gem_free_object_unlocked = drm_gem_cma_free_object, 169 + .gem_vm_ops = &drm_gem_cma_vm_ops, 170 + 171 + .enable_vblank = tve200_enable_vblank, 172 + .disable_vblank = tve200_disable_vblank, 173 + 174 + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 175 + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 176 + .gem_prime_import = drm_gem_prime_import, 177 + .gem_prime_export = drm_gem_prime_export, 178 + .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 179 + .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 180 + .gem_prime_vmap = drm_gem_cma_prime_vmap, 181 + .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 182 + .gem_prime_mmap = drm_gem_cma_prime_mmap, 183 + }; 184 + 185 + static int tve200_probe(struct platform_device *pdev) 186 + { 187 + struct device *dev = &pdev->dev; 188 + struct tve200_drm_dev_private *priv; 189 + struct drm_device *drm; 190 + struct resource *res; 191 + int irq; 192 + int ret; 193 + 194 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 195 + if (!priv) 196 + return -ENOMEM; 197 + 198 + drm = drm_dev_alloc(&tve200_drm_driver, dev); 199 + if (IS_ERR(drm)) 200 + return PTR_ERR(drm); 201 + platform_set_drvdata(pdev, drm); 202 + priv->drm = drm; 203 + drm->dev_private = priv; 204 + 205 + /* Clock the silicon so we can access the registers */ 206 + priv->pclk = devm_clk_get(dev, "PCLK"); 207 + if (IS_ERR(priv->pclk)) { 208 + dev_err(dev, "unable to get PCLK\n"); 209 + ret = PTR_ERR(priv->pclk); 210 + goto dev_unref; 211 + } 212 + ret = clk_prepare_enable(priv->pclk); 213 + if (ret) { 214 + dev_err(dev, "failed to enable PCLK\n"); 215 + goto dev_unref; 216 + } 217 + 218 + /* This clock is for the pixels (27MHz) */ 219 + priv->clk = devm_clk_get(dev, "TVE"); 220 + if (IS_ERR(priv->clk)) { 221 + dev_err(dev, "unable to get TVE clock\n"); 222 + ret = PTR_ERR(priv->clk); 223 + goto clk_disable; 224 + } 225 + 226 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 227 + priv->regs = devm_ioremap_resource(dev, res); 228 + if (!priv->regs) { 229 + dev_err(dev, "%s failed mmio\n", __func__); 230 + ret = -EINVAL; 231 + goto clk_disable; 232 + } 233 + 234 + irq = platform_get_irq(pdev, 0); 235 + if (!irq) { 236 + ret = -EINVAL; 237 + goto clk_disable; 238 + } 239 + 240 + /* turn off interrupts before requesting the irq */ 241 + writel(0, priv->regs + TVE200_INT_EN); 242 + 243 + ret = devm_request_irq(dev, irq, tve200_irq, 0, "tve200", priv); 244 + if (ret) { 245 + dev_err(dev, "failed to request irq %d\n", ret); 246 + goto clk_disable; 247 + } 248 + 249 + ret = tve200_modeset_init(drm); 250 + if (ret) 251 + goto clk_disable; 252 + 253 + ret = drm_dev_register(drm, 0); 254 + if (ret < 0) 255 + goto clk_disable; 256 + 257 + return 0; 258 + 259 + clk_disable: 260 + clk_disable_unprepare(priv->pclk); 261 + dev_unref: 262 + drm_dev_unref(drm); 263 + return ret; 264 + } 265 + 266 + static int tve200_remove(struct platform_device *pdev) 267 + { 268 + struct drm_device *drm = platform_get_drvdata(pdev); 269 + struct tve200_drm_dev_private *priv = drm->dev_private; 270 + 271 + drm_dev_unregister(drm); 272 + if (priv->fbdev) 273 + drm_fbdev_cma_fini(priv->fbdev); 274 + if (priv->panel) 275 + drm_panel_bridge_remove(priv->bridge); 276 + drm_mode_config_cleanup(drm); 277 + clk_disable_unprepare(priv->pclk); 278 + drm_dev_unref(drm); 279 + 280 + return 0; 281 + } 282 + 283 + static const struct of_device_id tve200_of_match[] = { 284 + { 285 + .compatible = "faraday,tve200", 286 + }, 287 + {}, 288 + }; 289 + 290 + static struct platform_driver tve200_driver = { 291 + .driver = { 292 + .name = "tve200", 293 + .of_match_table = of_match_ptr(tve200_of_match), 294 + }, 295 + .probe = tve200_probe, 296 + .remove = tve200_remove, 297 + }; 298 + module_platform_driver(tve200_driver); 299 + 300 + MODULE_DESCRIPTION(DRIVER_DESC); 301 + MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 302 + MODULE_LICENSE("GPL");
-2
drivers/gpu/drm/vc4/Makefile
··· 24 24 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o 25 25 26 26 obj-$(CONFIG_DRM_VC4) += vc4.o 27 - 28 - CFLAGS_vc4_trace_points.o := -I$(src)
+3 -12
drivers/gpu/drm/vc4/vc4_hdmi.c
··· 309 309 static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev, 310 310 struct drm_encoder *encoder) 311 311 { 312 - struct drm_connector *connector = NULL; 312 + struct drm_connector *connector; 313 313 struct vc4_hdmi_connector *hdmi_connector; 314 - int ret = 0; 315 314 316 315 hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector), 317 316 GFP_KERNEL); 318 - if (!hdmi_connector) { 319 - ret = -ENOMEM; 320 - goto fail; 321 - } 317 + if (!hdmi_connector) 318 + return ERR_PTR(-ENOMEM); 322 319 connector = &hdmi_connector->base; 323 320 324 321 hdmi_connector->encoder = encoder; ··· 333 336 drm_mode_connector_attach_encoder(connector, encoder); 334 337 335 338 return connector; 336 - 337 - fail: 338 - if (connector) 339 - vc4_hdmi_connector_destroy(connector); 340 - 341 - return ERR_PTR(ret); 342 339 } 343 340 344 341 static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder)
+1 -1
drivers/gpu/drm/vc4/vc4_trace.h
··· 59 59 60 60 /* This part must be outside protection */ 61 61 #undef TRACE_INCLUDE_PATH 62 - #define TRACE_INCLUDE_PATH . 62 + #define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/vc4 63 63 #include <trace/define_trace.h>
+2 -1
drivers/gpu/drm/zte/zx_drm_drv.c
··· 22 22 #include <drm/drm_fb_cma_helper.h> 23 23 #include <drm/drm_fb_helper.h> 24 24 #include <drm/drm_gem_cma_helper.h> 25 + #include <drm/drm_gem_framebuffer_helper.h> 25 26 #include <drm/drm_of.h> 26 27 #include <drm/drmP.h> 27 28 ··· 41 40 } 42 41 43 42 static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = { 44 - .fb_create = drm_fb_cma_create, 43 + .fb_create = drm_gem_fb_create, 45 44 .output_poll_changed = zx_drm_fb_output_poll_changed, 46 45 .atomic_check = drm_atomic_helper_check, 47 46 .atomic_commit = drm_atomic_helper_commit,
+17 -77
include/drm/drm_atomic.h
··· 144 144 struct __drm_crtcs_state { 145 145 struct drm_crtc *ptr; 146 146 struct drm_crtc_state *state, *old_state, *new_state; 147 - struct drm_crtc_commit *commit; 148 147 s32 __user *out_fence_ptr; 149 148 unsigned last_vblank_count; 150 149 }; ··· 236 237 struct drm_modeset_acquire_ctx *acquire_ctx; 237 238 238 239 /** 240 + * @fake_commit: 241 + * 242 + * Used for signaling unbound planes/connectors. 243 + * When a connector or plane is not bound to any CRTC, it's still important 244 + * to preserve linearity to prevent the atomic states from being freed to early. 245 + * 246 + * This commit (if set) is not bound to any crtc, but will be completed when 247 + * drm_atomic_helper_commit_hw_done() is called. 248 + */ 249 + struct drm_crtc_commit *fake_commit; 250 + 251 + /** 239 252 * @commit_work: 240 253 * 241 254 * Work item which can be used by the driver or helpers to execute the ··· 263 252 * @commit: CRTC commit 264 253 * 265 254 * Increases the reference of @commit. 255 + * 256 + * Returns: 257 + * The pointer to @commit, with reference increased. 266 258 */ 267 - static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) 259 + static inline struct drm_crtc_commit *drm_crtc_commit_get(struct drm_crtc_commit *commit) 268 260 { 269 261 kref_get(&commit->ref); 262 + return commit; 270 263 } 271 264 272 265 /** ··· 570 555 void drm_state_dump(struct drm_device *dev, struct drm_printer *p); 571 556 572 557 /** 573 - * for_each_connector_in_state - iterate over all connectors in an atomic update 574 - * @__state: &struct drm_atomic_state pointer 575 - * @connector: &struct drm_connector iteration cursor 576 - * @connector_state: &struct drm_connector_state iteration cursor 577 - * @__i: int iteration cursor, for macro-internal use 578 - * 579 - * This iterates over all connectors in an atomic update. Note that before the 580 - * software state is committed (by calling drm_atomic_helper_swap_state(), this 581 - * points to the new state, while afterwards it points to the old state. Due to 582 - * this tricky confusion this macro is deprecated. 583 - * 584 - * FIXME: 585 - * 586 - * Replace all usage of this with one of the explicit iterators below and then 587 - * remove this macro. 588 - */ 589 - #define for_each_connector_in_state(__state, connector, connector_state, __i) \ 590 - for ((__i) = 0; \ 591 - (__i) < (__state)->num_connector && \ 592 - ((connector) = (__state)->connectors[__i].ptr, \ 593 - (connector_state) = (__state)->connectors[__i].state, 1); \ 594 - (__i)++) \ 595 - for_each_if (connector) 596 - 597 - /** 598 558 * for_each_oldnew_connector_in_state - iterate over all connectors in an atomic update 599 559 * @__state: &struct drm_atomic_state pointer 600 560 * @connector: &struct drm_connector iteration cursor ··· 633 643 for_each_if (connector) 634 644 635 645 /** 636 - * for_each_crtc_in_state - iterate over all connectors in an atomic update 637 - * @__state: &struct drm_atomic_state pointer 638 - * @crtc: &struct drm_crtc iteration cursor 639 - * @crtc_state: &struct drm_crtc_state iteration cursor 640 - * @__i: int iteration cursor, for macro-internal use 641 - * 642 - * This iterates over all CRTCs in an atomic update. Note that before the 643 - * software state is committed (by calling drm_atomic_helper_swap_state(), this 644 - * points to the new state, while afterwards it points to the old state. Due to 645 - * this tricky confusion this macro is deprecated. 646 - * 647 - * FIXME: 648 - * 649 - * Replace all usage of this with one of the explicit iterators below and then 650 - * remove this macro. 651 - */ 652 - #define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \ 653 - for ((__i) = 0; \ 654 - (__i) < (__state)->dev->mode_config.num_crtc && \ 655 - ((crtc) = (__state)->crtcs[__i].ptr, \ 656 - (crtc_state) = (__state)->crtcs[__i].state, 1); \ 657 - (__i)++) \ 658 - for_each_if (crtc_state) 659 - 660 - /** 661 646 * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update 662 647 * @__state: &struct drm_atomic_state pointer 663 648 * @crtc: &struct drm_crtc iteration cursor ··· 690 725 (new_crtc_state) = (__state)->crtcs[__i].new_state, 1); \ 691 726 (__i)++) \ 692 727 for_each_if (crtc) 693 - 694 - /** 695 - * for_each_plane_in_state - iterate over all planes in an atomic update 696 - * @__state: &struct drm_atomic_state pointer 697 - * @plane: &struct drm_plane iteration cursor 698 - * @plane_state: &struct drm_plane_state iteration cursor 699 - * @__i: int iteration cursor, for macro-internal use 700 - * 701 - * This iterates over all planes in an atomic update. Note that before the 702 - * software state is committed (by calling drm_atomic_helper_swap_state(), this 703 - * points to the new state, while afterwards it points to the old state. Due to 704 - * this tricky confusion this macro is deprecated. 705 - * 706 - * FIXME: 707 - * 708 - * Replace all usage of this with one of the explicit iterators below and then 709 - * remove this macro. 710 - */ 711 - #define for_each_plane_in_state(__state, plane, plane_state, __i) \ 712 - for ((__i) = 0; \ 713 - (__i) < (__state)->dev->mode_config.num_total_plane && \ 714 - ((plane) = (__state)->planes[__i].ptr, \ 715 - (plane_state) = (__state)->planes[__i].state, 1); \ 716 - (__i)++) \ 717 - for_each_if (plane_state) 718 728 719 729 /** 720 730 * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update
+1 -1
include/drm/drm_bridge.h
··· 245 245 void *driver_private; 246 246 }; 247 247 248 - int drm_bridge_add(struct drm_bridge *bridge); 248 + void drm_bridge_add(struct drm_bridge *bridge); 249 249 void drm_bridge_remove(struct drm_bridge *bridge); 250 250 struct drm_bridge *of_drm_find_bridge(struct device_node *np); 251 251 int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
+8 -2
include/drm/drm_connector.h
··· 347 347 348 348 struct drm_atomic_state *state; 349 349 350 + /** 351 + * @commit: Tracks the pending commit to prevent use-after-free conditions. 352 + * 353 + * Is only set when @crtc is NULL. 354 + */ 355 + struct drm_crtc_commit *commit; 356 + 350 357 struct drm_tv_connector_state tv; 351 358 352 359 /** ··· 895 888 * This is protected by @drm_mode_config.connection_mutex. Note that 896 889 * nonblocking atomic commits access the current connector state without 897 890 * taking locks. Either by going through the &struct drm_atomic_state 898 - * pointers, see for_each_connector_in_state(), 899 - * for_each_oldnew_connector_in_state(), 891 + * pointers, see for_each_oldnew_connector_in_state(), 900 892 * for_each_old_connector_in_state() and 901 893 * for_each_new_connector_in_state(). Or through careful ordering of 902 894 * atomic commit operations as implemented in the atomic helpers, see
+23 -8
include/drm/drm_crtc.h
··· 253 253 */ 254 254 struct drm_pending_vblank_event *event; 255 255 256 + /** 257 + * @commit: 258 + * 259 + * This tracks how the commit for this update proceeds through the 260 + * various phases. This is never cleared, except when we destroy the 261 + * state, so that subsequent commits can synchronize with previous ones. 262 + */ 263 + struct drm_crtc_commit *commit; 264 + 256 265 struct drm_atomic_state *state; 257 266 }; 258 267 ··· 806 797 * This is protected by @mutex. Note that nonblocking atomic commits 807 798 * access the current CRTC state without taking locks. Either by going 808 799 * through the &struct drm_atomic_state pointers, see 809 - * for_each_crtc_in_state(), for_each_oldnew_crtc_in_state(), 810 - * for_each_old_crtc_in_state() and for_each_new_crtc_in_state(). Or 811 - * through careful ordering of atomic commit operations as implemented 812 - * in the atomic helpers, see &struct drm_crtc_commit. 800 + * for_each_oldnew_crtc_in_state(), for_each_old_crtc_in_state() and 801 + * for_each_new_crtc_in_state(). Or through careful ordering of atomic 802 + * commit operations as implemented in the atomic helpers, see 803 + * &struct drm_crtc_commit. 813 804 */ 814 805 struct drm_crtc_state *state; 815 806 ··· 817 808 * @commit_list: 818 809 * 819 810 * List of &drm_crtc_commit structures tracking pending commits. 820 - * Protected by @commit_lock. This list doesn't hold its own full 821 - * reference, but burrows it from the ongoing commit. Commit entries 822 - * must be removed from this list once the commit is fully completed, 823 - * but before it's correspoding &drm_atomic_state gets destroyed. 811 + * Protected by @commit_lock. This list holds its own full reference, 812 + * as does the ongoing commit. 813 + * 814 + * "Note that the commit for a state change is also tracked in 815 + * &drm_crtc_state.commit. For accessing the immediately preceding 816 + * commit in an atomic update it is recommended to just use that 817 + * pointer in the old CRTC state, since accessing that doesn't need 818 + * any locking or list-walking. @commit_list should only be used to 819 + * stall for framebuffer cleanup that's signalled through 820 + * &drm_crtc_commit.cleanup_done." 824 821 */ 825 822 struct list_head commit_list; 826 823
+17
include/drm/drm_dp_helper.h
··· 738 738 #define DP_RECEIVER_ALPM_STATUS 0x200b /* eDP 1.4 */ 739 739 # define DP_ALPM_LOCK_TIMEOUT_ERROR (1 << 0) 740 740 741 + #define DP_LANE0_1_STATUS_ESI 0x200c /* status same as 0x202 */ 742 + #define DP_LANE2_3_STATUS_ESI 0x200d /* status same as 0x203 */ 743 + #define DP_LANE_ALIGN_STATUS_UPDATED_ESI 0x200e /* status same as 0x204 */ 744 + #define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 */ 745 + 741 746 #define DP_DPRX_FEATURE_ENUMERATION_LIST 0x2210 /* DP 1.3 */ 742 747 # define DP_GTC_CAP (1 << 0) /* DP 1.3 */ 743 748 # define DP_SST_SPLIT_SDP_CAP (1 << 1) /* DP 1.4 */ ··· 875 870 876 871 u8 drm_dp_link_rate_to_bw_code(int link_rate); 877 872 int drm_dp_bw_code_to_link_rate(u8 link_bw); 873 + 874 + #define DP_SDP_AUDIO_TIMESTAMP 0x01 875 + #define DP_SDP_AUDIO_STREAM 0x02 876 + #define DP_SDP_EXTENSION 0x04 /* DP 1.1 */ 877 + #define DP_SDP_AUDIO_COPYMANAGEMENT 0x05 /* DP 1.2 */ 878 + #define DP_SDP_ISRC 0x06 /* DP 1.2 */ 879 + #define DP_SDP_VSC 0x07 /* DP 1.2 */ 880 + #define DP_SDP_CAMERA_GENERIC(i) (0x08 + (i)) /* 0-7, DP 1.3 */ 881 + #define DP_SDP_PPS 0x10 /* DP 1.4 */ 882 + #define DP_SDP_VSC_EXT_VESA 0x20 /* DP 1.4 */ 883 + #define DP_SDP_VSC_EXT_CEA 0x21 /* DP 1.4 */ 884 + /* 0x80+ CEA-861 infoframe types */ 878 885 879 886 struct edp_sdp_header { 880 887 u8 HB0; /* Secondary Data Packet ID */
+2
include/drm/drm_dp_mst_helper.h
··· 631 631 int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, 632 632 struct drm_dp_mst_topology_mgr *mgr, 633 633 int slots); 634 + int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, 635 + struct drm_dp_mst_port *port, bool power_up); 634 636 635 637 #endif
+2
include/drm/drm_edid.h
··· 341 341 342 342 #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE 343 343 struct edid *drm_load_edid_firmware(struct drm_connector *connector); 344 + int __drm_set_edid_firmware_path(const char *path); 345 + int __drm_get_edid_firmware_path(char *buf, size_t bufsize); 344 346 #else 345 347 static inline struct edid * 346 348 drm_load_edid_firmware(struct drm_connector *connector)
+1 -1
include/drm/drm_gem_framebuffer_helper.h
··· 2 2 #define __DRM_GEM_FB_HELPER_H__ 3 3 4 4 struct drm_device; 5 - struct drm_file; 6 5 struct drm_fb_helper_surface_size; 6 + struct drm_file; 7 7 struct drm_framebuffer; 8 8 struct drm_framebuffer_funcs; 9 9 struct drm_gem_object;
+1 -1
include/drm/drm_modeset_helper_vtables.h
··· 314 314 * implementation in drm_atomic_helper_check(). 315 315 * 316 316 * When using drm_atomic_helper_check_planes() this hook is called 317 - * after the &drm_plane_helper_funcs.atomc_check hook for planes, which 317 + * after the &drm_plane_helper_funcs.atomic_check hook for planes, which 318 318 * allows drivers to assign shared resources requested by planes in this 319 319 * callback here. For more complicated dependencies the driver can call 320 320 * the provided check helpers multiple times until the computed state
+8 -4
include/drm/drm_modeset_lock.h
··· 34 34 * @contended: used internally for -EDEADLK handling 35 35 * @locked: list of held locks 36 36 * @trylock_only: trylock mode used in atomic contexts/panic notifiers 37 + * @interruptible: whether interruptible locking should be used. 37 38 * 38 39 * Each thread competing for a set of locks must use one acquire 39 40 * ctx. And if any lock fxn returns -EDEADLK, it must backoff and ··· 60 59 * Trylock mode, use only for panic handlers! 61 60 */ 62 61 bool trylock_only; 62 + 63 + /* Perform interruptible waits on this context. */ 64 + bool interruptible; 63 65 }; 64 66 65 67 /** ··· 86 82 struct list_head head; 87 83 }; 88 84 85 + #define DRM_MODESET_ACQUIRE_INTERRUPTIBLE BIT(0) 86 + 89 87 void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx, 90 88 uint32_t flags); 91 89 void drm_modeset_acquire_fini(struct drm_modeset_acquire_ctx *ctx); 92 90 void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx); 93 - void drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx); 94 - int drm_modeset_backoff_interruptible(struct drm_modeset_acquire_ctx *ctx); 91 + int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx); 95 92 96 93 void drm_modeset_lock_init(struct drm_modeset_lock *lock); 97 94 ··· 116 111 117 112 int drm_modeset_lock(struct drm_modeset_lock *lock, 118 113 struct drm_modeset_acquire_ctx *ctx); 119 - int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, 120 - struct drm_modeset_acquire_ctx *ctx); 114 + int __must_check drm_modeset_lock_single_interruptible(struct drm_modeset_lock *lock); 121 115 void drm_modeset_unlock(struct drm_modeset_lock *lock); 122 116 123 117 struct drm_device;
+12 -4
include/drm/drm_plane.h
··· 123 123 */ 124 124 bool visible; 125 125 126 + /** 127 + * @commit: Tracks the pending commit to prevent use-after-free conditions, 128 + * and for async plane updates. 129 + * 130 + * May be NULL. 131 + */ 132 + struct drm_crtc_commit *commit; 133 + 126 134 struct drm_atomic_state *state; 127 135 }; 128 136 ··· 539 531 * This is protected by @mutex. Note that nonblocking atomic commits 540 532 * access the current plane state without taking locks. Either by going 541 533 * through the &struct drm_atomic_state pointers, see 542 - * for_each_plane_in_state(), for_each_oldnew_plane_in_state(), 543 - * for_each_old_plane_in_state() and for_each_new_plane_in_state(). Or 544 - * through careful ordering of atomic commit operations as implemented 545 - * in the atomic helpers, see &struct drm_crtc_commit. 534 + * for_each_oldnew_plane_in_state(), for_each_old_plane_in_state() and 535 + * for_each_new_plane_in_state(). Or through careful ordering of atomic 536 + * commit operations as implemented in the atomic helpers, see 537 + * &struct drm_crtc_commit. 546 538 */ 547 539 struct drm_plane_state *state; 548 540
+4
include/linux/sync_file.h
··· 25 25 * @file: file representing this fence 26 26 * @sync_file_list: membership in global file list 27 27 * @wq: wait queue for fence signaling 28 + * @flags: flags for the sync_file 28 29 * @fence: fence with the fences in the sync_file 29 30 * @cb: fence callback information 31 + * 32 + * flags: 33 + * POLL_ENABLED: whether userspace is currently poll()'ing or not 30 34 */ 31 35 struct sync_file { 32 36 struct file *file;
+2 -2
include/uapi/drm/drm_mode.h
··· 749 749 * If the number formats grew to 128, and formats 98-102 are 750 750 * supported with the modifier: 751 751 * 752 - * 0x0000003c00000000 0000000000000000 752 + * 0x0000007c00000000 0000000000000000 753 753 * ^ 754 - * |__offset = 64, formats = 0x3c00000000 754 + * |__offset = 64, formats = 0x7c00000000 755 755 * 756 756 */ 757 757 __u64 formats;