From b93658f83fa7f89cde5cfba7158da2be8cac42b2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 8 Mar 2017 15:12:44 +0100 Subject: drm/doc: Document drm_file.[hc] Well, mostly drm_file.h, and clean up all related things: - I didnt' figure out the difference between preclose and postclose. The existing explanation in drm-internals.rst didn't convince me, since it's also really outdated - we clean up pending DRM events in the core nowadays. I put a FIXME in for the future. - Another FIXME is to have a macro for default fops. - Lots of links all around, main areas are to tie the overview in drm_file.c more into the callbacks in struct drm_device, and the other is to link render/primary node code to the right sections in drm-uapi.rst. - Also moved the open/close stuff to drm_drv.h from drm-internals.rst, seems like the better place for that information. Since that section was rather outdated this amounted to full-on rewrite. A big missing piece here is some overview graph, but I think better to wait with that one until drm_device and drm_driver are also fully documented. v2: Nits from Sean. Reviewed-by: Sean Paul Reviewed-by: Liviu Dudau Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170308141257.12119-12-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-internals.rst | 52 +++---------------------------------- Documentation/gpu/drm-uapi.rst | 4 +++ 2 files changed, 7 insertions(+), 49 deletions(-) (limited to 'Documentation/gpu') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 3bb4d937cdfe..cbf8e52cd9bb 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -243,61 +243,15 @@ drivers. Open/Close, File Operations and IOCTLs ====================================== -Open and Close --------------- - -Open and close handlers. None of those methods are mandatory:: - - int (*firstopen) (struct drm_device *); - void (*lastclose) (struct drm_device *); - int (*open) (struct drm_device *, struct drm_file *); - void (*preclose) (struct drm_device *, struct drm_file *); - void (*postclose) (struct drm_device *, struct drm_file *); - -The firstopen method is called by the DRM core for legacy UMS (User Mode -Setting) drivers only when an application opens a device that has no -other opened file handle. UMS drivers can implement it to acquire device -resources. KMS drivers can't use the method and must acquire resources -in the load method instead. - -Similarly the lastclose method is called when the last application -holding a file handle opened on the device closes it, for both UMS and -KMS drivers. Additionally, the method is also called at module unload -time or, for hot-pluggable devices, when the device is unplugged. The -firstopen and lastclose calls can thus be unbalanced. - -The open method is called every time the device is opened by an -application. Drivers can allocate per-file private data in this method -and store them in the struct :c:type:`struct drm_file -` driver_priv field. Note that the open method is -called before firstopen. - -The close operation is split into preclose and postclose methods. -Drivers must stop and cleanup all per-file operations in the preclose -method. For instance pending vertical blanking and page flip events must -be cancelled. No per-file operation is allowed on the file handle after -returning from the preclose method. - -Finally the postclose method is called as the last step of the close -operation, right before calling the lastclose method if no other open -file handle exists for the device. Drivers that have allocated per-file -private data in the open method should free it here. - -The lastclose method should restore CRTC and plane properties to default -value, so that a subsequent open of the device will not inherit state -from the previous user. It can also be used to execute delayed power -switching state changes, e.g. in conjunction with the :ref:`vga_switcheroo` -infrastructure. Beyond that KMS drivers should not do any -further cleanup. Only legacy UMS drivers might need to clean up device -state so that the vga console or an independent fbdev driver could take -over. - File Operations --------------- .. kernel-doc:: drivers/gpu/drm/drm_file.c :doc: file operations +.. kernel-doc:: include/drm/drm_file.h + :internal: + .. kernel-doc:: drivers/gpu/drm/drm_file.c :export: diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index fcc228ef5bc4..352652810dab 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -21,6 +21,8 @@ libdrm Device Lookup :doc: getunique and setversion story +.. _drm_primary_node: + Primary Nodes, DRM Master and Authentication ============================================ @@ -103,6 +105,8 @@ is already rather painful for the DRM subsystem, with multiple different uAPIs for the same thing co-existing. If we add a few more complete mistakes into the mix every year it would be entirely unmanageable. +.. _drm_render_node: + Render nodes ============ -- cgit v1.2.3 From 2564d0b043cbe9d762f97104029281102cfe4be2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Mar 2017 16:16:35 +0100 Subject: drm/doc: Add KMS overview graphs Oh, the shiny and pretties! v2: Review from Laurent. Cc: Laurent Pinchart Acked-by: Eric Anholt Reviewed-by: Gabriel Krisman Bertazi Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170302151638.1882-3-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-kms-helpers.rst | 4 + Documentation/gpu/drm-kms.rst | 134 +++++++++++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 1 deletion(-) (limited to 'Documentation/gpu') diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 03040aa14fe8..012b6ff3ec3f 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -114,6 +114,8 @@ Framebuffer CMA Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c :export: +.. _drm_bridges: + Bridges ======= @@ -139,6 +141,8 @@ Bridge Helper Reference .. kernel-doc:: drivers/gpu/drm/drm_bridge.c :export: +.. _drm_panel_helper: + Panel Helper Reference ====================== diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 4d4068855ec4..bcf475f86e83 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -15,7 +15,139 @@ be setup by initializing the following fields. - struct drm_mode_config_funcs \*funcs; Mode setting functions. -Mode Configuration +Overview +======== + +.. kernel-render:: DOT + :alt: KMS Display Pipeline + :caption: KMS Display Pipeline Overview + + digraph "KMS" { + node [shape=box] + + subgraph cluster_static { + style=dashed + label="Static Objects" + + node [bgcolor=grey style=filled] + "drm_plane A" -> "drm_crtc" + "drm_plane B" -> "drm_crtc" + "drm_crtc" -> "drm_encoder A" + "drm_crtc" -> "drm_encoder B" + } + + subgraph cluster_user_created { + style=dashed + label="Userspace-Created" + + node [shape=oval] + "drm_framebuffer 1" -> "drm_plane A" + "drm_framebuffer 2" -> "drm_plane B" + } + + subgraph cluster_connector { + style=dashed + label="Hotpluggable" + + "drm_encoder A" -> "drm_connector A" + "drm_encoder B" -> "drm_connector B" + } + } + +The basic object structure KMS presents to userspace is fairly simple. +Framebuffers (represented by :c:type:`struct drm_framebuffer `, +see `Frame Buffer Abstraction`_) feed into planes. One or more (or even no) +planes feed their pixel data into a CRTC (represented by :c:type:`struct +drm_crtc `, see `CRTC Abstraction`_) for blending. The precise +blending step is explained in more detail in `Plane Composition Properties`_ and +related chapters. + +For the output routing the first step is encoders (represented by +:c:type:`struct drm_encoder `, see `Encoder Abstraction`_). Those +are really just internal artifacts of the helper libraries used to implement KMS +drivers. Besides that they make it unecessarily more complicated for userspace +to figure out which connections between a CRTC and a connector are possible, and +what kind of cloning is supported, they serve no purpose in the userspace API. +Unfortunately encoders have been exposed to userspace, hence can't remove them +at this point. Futhermore the exposed restrictions are often wrongly set by +drivers, and in many cases not powerful enough to express the real restrictions. +A CRTC can be connected to multiple encoders, and for an active CRTC there must +be at least one encoder. + +The final, and real, endpoint in the display chain is the connector (represented +by :c:type:`struct drm_connector `, see `Connector +Abstraction`_). Connectors can have different possible encoders, but the kernel +driver selects which encoder to use for each connector. The use case is DVI, +which could switch between an analog and a digital encoder. Encoders can also +drive multiple different connectors. There is exactly one active connector for +every active encoder. + +Internally the output pipeline is a bit more complex and matches today's +hardware more closely: + +.. kernel-render:: DOT + :alt: KMS Output Pipeline + :caption: KMS Output Pipeline + + digraph "Output Pipeline" { + node [shape=box] + + subgraph { + "drm_crtc" [bgcolor=grey style=filled] + } + + subgraph cluster_internal { + style=dashed + label="Internal Pipeline" + { + node [bgcolor=grey style=filled] + "drm_encoder A"; + "drm_encoder B"; + "drm_encoder C"; + } + + { + node [bgcolor=grey style=filled] + "drm_encoder B" -> "drm_bridge B" + "drm_encoder C" -> "drm_bridge C1" + "drm_bridge C1" -> "drm_bridge C2"; + } + } + + "drm_crtc" -> "drm_encoder A" + "drm_crtc" -> "drm_encoder B" + "drm_crtc" -> "drm_encoder C" + + + subgraph cluster_output { + style=dashed + label="Outputs" + + "drm_encoder A" -> "drm_connector A"; + "drm_bridge B" -> "drm_connector B"; + "drm_bridge C2" -> "drm_connector C"; + + "drm_panel" + } + } + +Internally two additional helper objects come into play. First, to be able to +share code for encoders (sometimes on the same SoC, sometimes off-chip) one or +more :ref:`drm_bridges` (represented by :c:type:`struct drm_bridge +`) can be linked to an encoder. This link is static and cannot be +changed, which means the cross-bar (if there is any) needs to be mapped between +the CRTC and any encoders. Often for drivers with bridges there's no code left +at the encoder level. Atomic drivers can leave out all the encoder callbacks to +essentially only leave a dummy routing object behind, which is needed for +backwards compatibility since encoders are exposed to userspace. + +The second object is for panels, represented by :c:type:`struct drm_panel +`, see :ref:`drm_panel_helper`. Panels do not have a fixed binding +point, but are generally linked to the driver private structure that embeds +:c:type:`struct drm_connector `. + +Note that currently the bridge chaining and interactions with connectors and +panels are still in-flux and not really fully sorted out yet. KMS Core Structures and Functions ================================= -- cgit v1.2.3 From 1ea3576874790ba81ab00c3a0f1a3fc23e687062 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Mar 2017 16:16:36 +0100 Subject: drm/doc: Consistent kerneldoc include order First overview text (if there is any), then headers (since generally you want to start out with the data structures), then all the other stuff with functions. Most of this is pre-shpinx, since with the old docbook only the overview stuff was pulled in directly. Everything else was put in a per-section index, so include order didn't really matter. Acked-by: Eric Anholt Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170302151638.1882-4-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-internals.rst | 6 +++--- Documentation/gpu/drm-kms-helpers.rst | 22 +++++++++++----------- Documentation/gpu/drm-kms.rst | 24 ++++++++++++------------ Documentation/gpu/drm-mm.rst | 24 ++++++++++++------------ 4 files changed, 38 insertions(+), 38 deletions(-) (limited to 'Documentation/gpu') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index cbf8e52cd9bb..a09c721f9e89 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -140,12 +140,12 @@ Device Instance and Driver Handling .. kernel-doc:: drivers/gpu/drm/drm_drv.c :doc: driver instance overview -.. kernel-doc:: drivers/gpu/drm/drm_drv.c - :export: - .. kernel-doc:: include/drm/drm_drv.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_drv.c + :export: + Driver Load ----------- diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 012b6ff3ec3f..050ebe81d256 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -37,10 +37,10 @@ Modeset Helper Reference for Common Vtables =========================================== .. kernel-doc:: include/drm/drm_modeset_helper_vtables.h - :internal: + :doc: overview .. kernel-doc:: include/drm/drm_modeset_helper_vtables.h - :doc: overview + :internal: Atomic Modeset Helper Functions Reference ========================================= @@ -84,27 +84,27 @@ Legacy CRTC/Modeset Helper Functions Reference Simple KMS Helper Reference =========================== +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :doc: overview + .. kernel-doc:: include/drm/drm_simple_kms_helper.h :internal: .. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c :export: -.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c - :doc: overview - fbdev Helper Functions Reference ================================ .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :doc: fbdev helpers -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c - :export: - .. kernel-doc:: include/drm/drm_fb_helper.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :export: + Framebuffer CMA Helper Functions Reference ========================================== @@ -146,15 +146,15 @@ Bridge Helper Reference Panel Helper Reference ====================== +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :doc: drm panel + .. kernel-doc:: include/drm/drm_panel.h :internal: .. kernel-doc:: drivers/gpu/drm/drm_panel.c :export: -.. kernel-doc:: drivers/gpu/drm/drm_panel.c - :doc: drm panel - Display Port Helper Functions Reference ======================================= diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index bcf475f86e83..b11c537c73f4 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -152,12 +152,12 @@ panels are still in-flux and not really fully sorted out yet. KMS Core Structures and Functions ================================= -.. kernel-doc:: drivers/gpu/drm/drm_mode_config.c - :export: - .. kernel-doc:: include/drm/drm_mode_config.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_mode_config.c + :export: + Modeset Base Object Abstraction =============================== @@ -170,12 +170,12 @@ Modeset Base Object Abstraction Atomic Mode Setting Function Reference ====================================== -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :export: - .. kernel-doc:: include/drm/drm_atomic.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :export: + CRTC Abstraction ================ @@ -200,12 +200,12 @@ Frame Buffer Abstraction Frame Buffer Functions Reference -------------------------------- -.. kernel-doc:: drivers/gpu/drm/drm_framebuffer.c - :export: - .. kernel-doc:: include/drm/drm_framebuffer.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_framebuffer.c + :export: + DRM Format Handling =================== @@ -508,8 +508,8 @@ operation handler. Vertical Blanking and Interrupt Handling Functions Reference ------------------------------------------------------------ -.. kernel-doc:: drivers/gpu/drm/drm_irq.c - :export: - .. kernel-doc:: include/drm/drm_irq.h :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_irq.c + :export: diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index d7a29d41789f..96b9c34c21e4 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -365,36 +365,36 @@ from the client in libdrm. GEM Function Reference ---------------------- -.. kernel-doc:: drivers/gpu/drm/drm_gem.c - :export: - .. kernel-doc:: include/drm/drm_gem.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_gem.c + :export: + GEM CMA Helper Functions Reference ---------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c :doc: cma helpers -.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c - :export: - .. kernel-doc:: include/drm/drm_gem_cma_helper.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :export: + VMA Offset Manager ================== .. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c :doc: vma offset manager -.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c - :export: - .. kernel-doc:: include/drm/drm_vma_manager.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :export: + PRIME Buffer Sharing ==================== @@ -473,12 +473,12 @@ LRU Scan/Eviction Support DRM MM Range Allocator Function References ------------------------------------------ -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :export: - .. kernel-doc:: include/drm/drm_mm.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :export: + DRM Cache Handling ================== -- cgit v1.2.3 From b2b82c26c7c1702cacde241cf63137eddd6524bf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Mar 2017 16:16:37 +0100 Subject: drm/doc: diagram for mode objects and properties Resulted in confusion a few times in the past. v2: Spelling fix (Eric). Cc: Eric Anholt Acked-by: Eric Anholt Cc: Laurent Pinchart Cc: Manasi Navare Reviewed-by: Gabriel Krisman Bertazi Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170302151638.1882-5-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-kms.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'Documentation/gpu') diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index b11c537c73f4..1c42448c7aae 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -161,6 +161,28 @@ KMS Core Structures and Functions Modeset Base Object Abstraction =============================== +.. kernel-render:: DOT + :alt: Mode Objects and Properties + :caption: Mode Objects and Properties + + digraph { + node [shape=box] + + "drm_property A" -> "drm_mode_object A" + "drm_property A" -> "drm_mode_object B" + "drm_property B" -> "drm_mode_object A" + } + +The base structure for all KMS objects is :c:type:`struct drm_mode_object +`. One of the base services it provides is tracking properties, +which are especially important for the atomic IOCTL (see `Atomic Mode +Setting`_). The somewhat surprising part here is that properties are not +directly instantiated on each object, but free-standing mode objects themselves, +represented by :c:type:`struct drm_property `, which only specify +the type and value range of a property. Any given property can be attached +multiple times to different objects using :c:func:`drm_object_attach_property() +`. + .. kernel-doc:: include/drm/drm_mode_object.h :internal: -- cgit v1.2.3 From 4a8e2292874e57ab6245ee16a8048729423d289d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Mar 2017 16:16:38 +0100 Subject: drm/doc: atomic overview, with graph I want to split up a few more things and document some details better (like how exactly to subclass drm_atomic_state). And maybe also split up the helpers a bit per-topic, but this should be a ok-ish start for better atomic overview. v2: Spelling and clarifications (Eric). v3: Implement suggestion from Gabriel to fix the graph. v4: Review from Laurent. Reviewed-by: Laurent Pinchart Cc: Gabriel Krisman Bertazi Acked-by: Eric Anholt Cc: Eric Anholt Cc: Laurent Pinchart Cc: Harry Wentland Reviewed-by: Gabriel Krisman Bertazi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170302151638.1882-6-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-kms-helpers.rst | 2 + Documentation/gpu/drm-kms.rst | 84 ++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) (limited to 'Documentation/gpu') diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 050ebe81d256..ac53c0b893f6 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -42,6 +42,8 @@ Modeset Helper Reference for Common Vtables .. kernel-doc:: include/drm/drm_modeset_helper_vtables.h :internal: +.. _drm_atomic_helper: + Atomic Modeset Helper Functions Reference ========================================= diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 1c42448c7aae..bfecd21a8cdf 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -189,8 +189,90 @@ multiple times to different objects using :c:func:`drm_object_attach_property() .. kernel-doc:: drivers/gpu/drm/drm_mode_object.c :export: +Atomic Mode Setting +=================== + + +.. kernel-render:: DOT + :alt: Mode Objects and Properties + :caption: Mode Objects and Properties + + digraph { + node [shape=box] + + subgraph cluster_state { + style=dashed + label="Free-standing state" + + "drm_atomic_state" -> "duplicated drm_plane_state A" + "drm_atomic_state" -> "duplicated drm_plane_state B" + "drm_atomic_state" -> "duplicated drm_crtc_state" + "drm_atomic_state" -> "duplicated drm_connector_state" + "drm_atomic_state" -> "duplicated driver private state" + } + + subgraph cluster_current { + style=dashed + label="Current state" + + "drm_device" -> "drm_plane A" + "drm_device" -> "drm_plane B" + "drm_device" -> "drm_crtc" + "drm_device" -> "drm_connector" + "drm_device" -> "driver private object" + + "drm_plane A" -> "drm_plane_state A" + "drm_plane B" -> "drm_plane_state B" + "drm_crtc" -> "drm_crtc_state" + "drm_connector" -> "drm_connector_state" + "driver private object" -> "driver private state" + } + + "drm_atomic_state" -> "drm_device" [label="atomic_commit"] + "duplicated drm_plane_state A" -> "drm_device"[style=invis] + } + +Atomic provides transactional modeset (including planes) updates, but a +bit differently from the usual transactional approach of try-commit and +rollback: + +- Firstly, no hardware changes are allowed when the commit would fail. This + allows us to implement the DRM_MODE_ATOMIC_TEST_ONLY mode, which allows + userspace to explore whether certain configurations would work or not. + +- This would still allow setting and rollback of just the software state, + simplifying conversion of existing drivers. But auditing drivers for + correctness of the atomic_check code becomes really hard with that: Rolling + back changes in data structures all over the place is hard to get right. + +- Lastly, for backwards compatibility and to support all use-cases, atomic + updates need to be incremental and be able to execute in parallel. Hardware + doesn't always allow it, but where possible plane updates on different CRTCs + should not interfere, and not get stalled due to output routing changing on + different CRTCs. + +Taken all together there's two consequences for the atomic design: + +- The overall state is split up into per-object state structures: + :c:type:`struct drm_plane_state ` for planes, :c:type:`struct + drm_crtc_state ` for CRTCs and :c:type:`struct + drm_connector_state ` for connectors. These are the only + objects with userspace-visible and settable state. For internal state drivers + can subclass these structures through embeddeding, or add entirely new state + structures for their globally shared hardware functions. + +- An atomic update is assembled and validated as an entirely free-standing pile + of structures within the :c:type:`drm_atomic_state ` + container. Again drivers can subclass that container for their own state + structure tracking needs. Only when a state is committed is it applied to the + driver and modeset objects. This way rolling back an update boils down to + releasing memory and unreferencing objects like framebuffers. + +Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed +coverage of specific topics. + Atomic Mode Setting Function Reference -====================================== +-------------------------------------- .. kernel-doc:: include/drm/drm_atomic.h :internal: -- cgit v1.2.3 From 3ad33ae2bc800496e979b9f7920a57835740083d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 13 Mar 2017 16:53:59 +0530 Subject: drm: Add SCDC helpers SCDC is a mechanism defined in the HDMI 2.0 specification that allows the source and sink devices to communicate. This commit introduces helpers to access the SCDC and provides the symbolic names for the various registers defined in the specification. V2: Rebase. V3: Added R-B from Jose. V4: Rebase V5: Addressed review comments from Ville - Handle the I2c return values in a better way (dp_dual_mode) - Make the macros for SCDC Major/Minor more readable, by adding a 'GET' in the macro names V6: Rebase V7: Rebase V8: Rebase V9: Rebase V10: Rebase Signed-off-by: Thierry Reding Signed-off-by: Shashank Sharma Reviewed-by: Jose Abreu Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1489404244-16608-2-git-send-email-shashank.sharma@intel.com --- Documentation/gpu/drm-kms-helpers.rst | 12 ++++ drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/drm_scdc_helper.c | 123 +++++++++++++++++++++++++++++++ include/drm/drm_scdc_helper.h | 132 ++++++++++++++++++++++++++++++++++ 4 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/drm_scdc_helper.c create mode 100644 include/drm/drm_scdc_helper.h (limited to 'Documentation/gpu') diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index ac53c0b893f6..c075aadd7078 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -223,6 +223,18 @@ EDID Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_edid.c :export: +SCDC Helper Functions Reference +=============================== + +.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c + :doc: scdc helpers + +.. kernel-doc:: include/drm/drm_scdc_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c + :export: + Rectangle Utilities Reference ============================= diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 59aae43005ee..59f0f9b696eb 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -31,7 +31,8 @@ drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ - drm_simple_kms_helper.o drm_modeset_helper.o + drm_simple_kms_helper.o drm_modeset_helper.o \ + drm_scdc_helper.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c new file mode 100644 index 000000000000..c2dd33f89c17 --- /dev/null +++ b/drivers/gpu/drm/drm_scdc_helper.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include + +/** + * DOC: scdc helpers + * + * Status and Control Data Channel (SCDC) is a mechanism introduced by the + * HDMI 2.0 specification. It is a point-to-point protocol that allows the + * HDMI source and HDMI sink to exchange data. The same I2C interface that + * is used to access EDID serves as the transport mechanism for SCDC. + */ + +#define SCDC_I2C_SLAVE_ADDRESS 0x54 + +/** + * drm_scdc_read - read a block of data from SCDC + * @adapter: I2C controller + * @offset: start offset of block to read + * @buffer: return location for the block to read + * @size: size of the block to read + * + * Reads a block of data from SCDC, starting at a given offset. + * + * Returns: + * 0 on success, negative error code on failure. + */ +ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer, + size_t size) +{ + int ret; + struct i2c_msg msgs[2] = { + { + .addr = SCDC_I2C_SLAVE_ADDRESS, + .flags = 0, + .len = 1, + .buf = &offset, + }, { + .addr = SCDC_I2C_SLAVE_ADDRESS, + .flags = I2C_M_RD, + .len = size, + .buf = buffer, + } + }; + + ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + return ret; + if (ret != ARRAY_SIZE(msgs)) + return -EPROTO; + + return 0; +} +EXPORT_SYMBOL(drm_scdc_read); + +/** + * drm_scdc_write - write a block of data to SCDC + * @adapter: I2C controller + * @offset: start offset of block to write + * @buffer: block of data to write + * @size: size of the block to write + * + * Writes a block of data to SCDC, starting at a given offset. + * + * Returns: + * 0 on success, negative error code on failure. + */ +ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset, + const void *buffer, size_t size) +{ + struct i2c_msg msg = { + .addr = SCDC_I2C_SLAVE_ADDRESS, + .flags = 0, + .len = 1 + size, + .buf = NULL, + }; + void *data; + int err; + + data = kmalloc(1 + size, GFP_TEMPORARY); + if (!data) + return -ENOMEM; + + msg.buf = data; + + memcpy(data, &offset, sizeof(offset)); + memcpy(data + 1, buffer, size); + + err = i2c_transfer(adapter, &msg, 1); + + kfree(data); + + if (err < 0) + return err; + if (err != 1) + return -EPROTO; + + return 0; +} +EXPORT_SYMBOL(drm_scdc_write); diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h new file mode 100644 index 000000000000..9c52deb13df4 --- /dev/null +++ b/include/drm/drm_scdc_helper.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef DRM_SCDC_HELPER_H +#define DRM_SCDC_HELPER_H + +#include +#include + +#define SCDC_SINK_VERSION 0x01 + +#define SCDC_SOURCE_VERSION 0x02 + +#define SCDC_UPDATE_0 0x10 +#define SCDC_READ_REQUEST_TEST (1 << 2) +#define SCDC_CED_UPDATE (1 << 1) +#define SCDC_STATUS_UPDATE (1 << 0) + +#define SCDC_UPDATE_1 0x11 + +#define SCDC_TMDS_CONFIG 0x20 +#define SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 (1 << 1) +#define SCDC_TMDS_BIT_CLOCK_RATIO_BY_10 (0 << 1) +#define SCDC_SCRAMBLING_ENABLE (1 << 0) + +#define SCDC_SCRAMBLER_STATUS 0x21 +#define SCDC_SCRAMBLING_STATUS (1 << 0) + +#define SCDC_CONFIG_0 0x30 +#define SCDC_READ_REQUEST_ENABLE (1 << 0) + +#define SCDC_STATUS_FLAGS_0 0x40 +#define SCDC_CH2_LOCK (1 < 3) +#define SCDC_CH1_LOCK (1 < 2) +#define SCDC_CH0_LOCK (1 < 1) +#define SCDC_CH_LOCK_MASK (SCDC_CH2_LOCK | SCDC_CH1_LOCK | SCDC_CH0_LOCK) +#define SCDC_CLOCK_DETECT (1 << 0) + +#define SCDC_STATUS_FLAGS_1 0x41 + +#define SCDC_ERR_DET_0_L 0x50 +#define SCDC_ERR_DET_0_H 0x51 +#define SCDC_ERR_DET_1_L 0x52 +#define SCDC_ERR_DET_1_H 0x53 +#define SCDC_ERR_DET_2_L 0x54 +#define SCDC_ERR_DET_2_H 0x55 +#define SCDC_CHANNEL_VALID (1 << 7) + +#define SCDC_ERR_DET_CHECKSUM 0x56 + +#define SCDC_TEST_CONFIG_0 0xc0 +#define SCDC_TEST_READ_REQUEST (1 << 7) +#define SCDC_TEST_READ_REQUEST_DELAY(x) ((x) & 0x7f) + +#define SCDC_MANUFACTURER_IEEE_OUI 0xd0 +#define SCDC_MANUFACTURER_IEEE_OUI_SIZE 3 + +#define SCDC_DEVICE_ID 0xd3 +#define SCDC_DEVICE_ID_SIZE 8 + +#define SCDC_DEVICE_HARDWARE_REVISION 0xdb +#define SCDC_GET_DEVICE_HARDWARE_REVISION_MAJOR(x) (((x) >> 4) & 0xf) +#define SCDC_GET_DEVICE_HARDWARE_REVISION_MINOR(x) (((x) >> 0) & 0xf) + +#define SCDC_DEVICE_SOFTWARE_MAJOR_REVISION 0xdc +#define SCDC_DEVICE_SOFTWARE_MINOR_REVISION 0xdd + +#define SCDC_MANUFACTURER_SPECIFIC 0xde +#define SCDC_MANUFACTURER_SPECIFIC_SIZE 34 + +ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer, + size_t size); +ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset, + const void *buffer, size_t size); + +/** + * drm_scdc_readb - read a single byte from SCDC + * @adapter: I2C adapter + * @offset: offset of register to read + * @value: return location for the register value + * + * Reads a single byte from SCDC. This is a convenience wrapper around the + * drm_scdc_read() function. + * + * Returns: + * 0 on success or a negative error code on failure. + */ +static inline int drm_scdc_readb(struct i2c_adapter *adapter, u8 offset, + u8 *value) +{ + return drm_scdc_read(adapter, offset, value, sizeof(*value)); +} + +/** + * drm_scdc_writeb - write a single byte to SCDC + * @adapter: I2C adapter + * @offset: offset of register to read + * @value: return location for the register value + * + * Writes a single byte to SCDC. This is a convenience wrapper around the + * drm_scdc_write() function. + * + * Returns: + * 0 on success or a negative error code on failure. + */ +static inline int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset, + u8 value) +{ + return drm_scdc_write(adapter, offset, &value, sizeof(value)); +} + +#endif -- cgit v1.2.3