SlideShare ist ein Scribd-Unternehmen logo
1 von 66
Downloaden Sie, um offline zu lesen
Anatomy of an Atomic
KMS Driver
Kernel Recipes 2015
Paris
Laurent Pinchart
laurent.pinchart@ideasonboard.com
DRM KMS?
APIs
DRM
● Memory Management
● Vertical Blanking
● Version, Authentication,
Master, ...
KMS
● Device Model
● Frame Buffer
● Modes
● Page Flip
● Planes
● Cursor, Gamma, ...
Device Model
Frame Buffer
(memory)
CRTC Encoder Connector
Planes
(memory)
Encoder
Connector
Connector
Device Model - SoC
Frame Buffer
(memory)
CRTC Encoder Connector
Plane
(memory)
SoCMemory Off-Chip
Encoder Connector
KMS – Scanout
Frame Buffer
KMS – Composition
CRTC
Plane(s)
Composition
KMS – Frame Buffer
CRTC
Frame Buffer
GEM
Object(s)
Memory
● width
● height
● format
● pitches
● offsets
Properties
DRM/KMS – GEM Object
CRTC
Frame Buffer
GEM Object
● width
● height
● bpp
● pitch
● size
Properties
Memory
DRM – Handles
Process A
Local
Handle
GEM
Object
Process B
Send FD
SCM_RIGHTS
Global
FD
1 2
Global
FD
4
Local
Handle
3
Active
Area
KMS – Modes (1/2)
sync
back porch
front porch
active area
Active
Area
KMS – Modes (2/2)
sync
back porch
front porch
active area
hdisplay
hsync_start
htotal
hsync_end
KMS – Mode Setting
crtc
fb
Active
Area
x
y
mode.hdisplay
mode.vdisplay
*connectors
num_connectors
mode
struct drm_mode_set {
struct drm_framebuffer *fb;
struct drm_crtc *crtc;
struct drm_display_mode *mode;
uint32_t x;
uint32_t y;
struct drm_connector **connectors;
size_t num_connectors;
};
KMS – Page Flipping
crtc
fb
*connectors
num_connectors
struct drm_mode_crtc_page_flip {
__u32 crtc_id;
__u32 fb_id;
__u32 flags;
__u32 reserved;
__u64 user_data;
};
plane
KMS – Atomic Update
fb
Active
Area
offset
pitch
width
height
mode
connectors
crtc
connector
plane
state
DRM_IOCTL_
MODE_ATOMIC
Properties
KMS – Atomic Update
crtc
connector
plane
device
->atomic_commit()
crtc
connector
plane
state
Properties
->atomic_check()
KMS – Atomic Update
#define DRM_MODE_PAGE_FLIP_EVENT 0x01
#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
struct drm_mode_atomic {
__u32 flags;
__u32 count_objs;
__u64 objs_ptr;
__u64 count_props_ptr;
__u64 props_ptr;
__u64 prop_values_ptr;
__u64 reserved;
__u64 user_data;
};
kerneldoc
drivers/gpu/drm/*
Documentation/
DocBook/drm.tmpl
Please contribute
Documentation
Disclaimer
Code Ahead
Locking and error
handling omitted for
readability
drm_* = core
(rcar_du_)* = driver
Cheat Sheet
Device Probe (1/2)
struct drm_driver rcar_du_driver = {
...
};
int rcar_du_probe(struct platform_device *pdev)
{
struct drm_device *dev;
...
dev = drm_dev_alloc(&rcar_du_driver,
&pdev->dev);
...
}
Device Probe (2/2)
int rcar_du_probe(struct platform_device *pdev)
{
struct rcar_du_device *rcdu;
struct drm_device *dev;
...
rcdu = kzalloc(sizeof(*rcdu), GFP_KERNEL);
dev->dev_private = rcdu;
/* Memory, clocks, regulators, ... */
...
drm_dev_register(dev, 0);
...
}
Device Removal
int rcar_du_remove(struct platform_device *pdev)
{
struct rcar_du_device *rcdu =
platform_get_drvdata(pdev);
struct drm_device *dev = rcdu->ddev;
drm_dev_unregister(dev);
...
drm_dev_unref(dev);
return 0;
}
Driver Information
struct drm_driver rcar_du_driver = {
.driver_features = DRIVER_HAVE_IRQ |
DRIVER_GEM | DRIVER_MODESET |
DRIVER_PRIME | DRIVER_ATOMIC,
.name = "rcar-du",
.desc = "Renesas R-Car Display Unit",
.date = "20130110",
.major = 1,
.minor = 0,
.patchlevel = 0,
...
};
File Operations
struct file_operations rcar_du_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
.compat_ioctl = drm_compat_ioctl,
.poll = drm_poll,
.read = drm_read,
.fasync = drm_fasync,
.llseek = no_llseek,
.mmap = ...,
};
struct drm_driver rcar_du_driver = {
.fops = &rcar_du_fops,
};
IRQ Installation
int rcar_du_probe(struct platform_device *pdev)
{
...
drm_irq_install(dev);
/* Behind the scene:
* request_irq(platform_get_irq(..., 0))
*/
...
}
struct drm_driver rcar_du_driver = {
/* .irq_preinstall */
.irq_handler = rcar_du_irq,
/* .irq_postinstall */
};
Mode Config
struct drm_mode_config_funcs modecfg_funcs = {
.fb_create = ...,
};
int rcar_du_probe(struct platform_device *pdev)
{
...
drm_mode_config_init(dev);
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
dev->mode_config.max_width = 4095;
dev->mode_config.max_height = 2047;
dev->mode_config.funcs =
&rcar_du_modecfg_funcs;
...
}
GEM
struct file_operations rcar_du_fops = {
.mmap = drm_gem_cma_mmap,
};
struct drm_driver rcar_du_driver = {
.gem_free_object = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
};
GEM – Dumb Objects
struct drm_driver rcar_du_driver = {
.dumb_create = drm_gem_cma_dumb_create,
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
.dumb_destroy = drm_gem_cma_dumb_destroy,
};
GEM – PRIME
struct drm_driver rcar_du_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_cma_dmabuf_import,
.gem_prime_export = drm_gem_cma_dmabuf_export,
};
Frame Buffer
drm_framebuffer *
rcar_du_fb_create(struct drm_device *dev,
struct drm_file *file_priv,
struct drm_mode_fb_cmd2 *mode_cmd)
{
/* Validate the pixel format, size and pitches */
...
return drm_fb_cma_create(dev, file_priv,
mode_cmd);
}
struct drm_mode_config_funcs rcar_du_modecfg_funcs =
{
.fb_create = rcar_du_fb_create,
};
Initialization – CRTC
struct drm_crtc_funcs crtc_funcs = {
.destroy = drm_crtc_cleanup,
...
};
int rcar_du_probe(struct platform_device *pdev)
{
struct drm_device *dev;
struct drm_crtc *crtc;
...
drm_crtc_init(dev, crtc, &crtc_funcs);
...
}
Initialization – Encoder
struct drm_encoder_funcs encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
int rcar_du_probe(struct platform_device *pdev)
{
struct drm_device *dev;
struct drm_encoder *encoder;
...
encoder->possible_crtcs = 1 << crtc;
drm_encoder_init(dev, encoder, &encoder_funcs,
DRM_MODE_ENCODER_DAC);
...
}
Initialization – Connector
struct drm_connector_funcs connector_funcs = {
.destroy = drm_connector_cleanup,
...
};
int rcar_du_probe(struct platform_device *pdev)
{
struct drm_device *dev;
struct drm_connector *connector;
...
connector->display_info.width_mm = ...;
connector->display_info.height_mm = ...;
drm_connector_init(dev, connector,
&connector_funcs, DRM_MODE_CONNECTOR_VGA);
drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector,
encoder);
}
Initialization – Plane
struct drm_plane_funcs plane_funcs = {
.destroy = drm_plane_cleanup,
...
};
uint32_t formats[] = {
DRM_FORMAT_RGB565, ...
};
int rcar_du_probe(struct platform_device *pdev)
{
struct drm_plane *plane = ...;
...
drm_universal_plane_init(dev, plane, crtcs,
&plane_funcs, formats,
ARRAY_SIZE(formats),
DRM_PLANE_TYPE_PRIMARY);
/* DRM_PLANE_TYPE_OVERLAY */
}
Modes Discovery (1/2)
struct drm_connector_funcs connector_funcs = {
.fill_modes = ...,
};
int (*fill_modes)(struct drm_connector *connector,
uint32_t max_width, uint32_t max_height);
Modes Discovery (2/2)
struct drm_connector_funcs connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
};
struct drm_connector_helper_funcs connector_helper_funcs =
{
.get_modes = rcar_du_vga_connector_get_modes,
.mode_valid = rcar_du_vga_connector_mode_valid,
};
CoreHelpers
State – CRTC
struct drm_crtc_funcs crtc_funcs = {
.reset = drm_atomic_helper_crtc_reset,
.atomic_duplicate_state =
drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state =
drm_atomic_helper_crtc_destroy_state,
};
struct drm_crtc_state {
struct drm_crtc *crtc;
bool enable;
bool active;
bool planes_changed : 1;
bool mode_changed : 1;
bool active_changed : 1;
...
};
State – Connector
struct drm_connector_funcs connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state =
drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state =
drm_atomic_helper_connector_destroy_state,
};
struct drm_connector_state {
struct drm_connector *connector;
struct drm_crtc *crtc;
struct drm_encoder *best_encoder;
struct drm_atomic_state *state;
};
State – Plane (1/5)
struct drm_plane_funcs plane_funcs = {
.reset = rcar_du_plane_reset,
.atomic_duplicate_state =
rcar_du_plane_atomic_duplicate_state,
.atomic_destroy_state =
rcar_du_plane_atomic_destroy_state,
};
struct drm_plane_state {
struct drm_plane *plane;
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
struct fence *fence;
int32_t crtc_x, crtc_y;
uint32_t crtc_w, crtc_h;
...
};
State – Plane (2/5)
struct rcar_du_plane_state {
struct drm_plane_state state;
const struct rcar_du_format_info *format;
int hwindex;
unsigned int alpha;
unsigned int colorkey;
unsigned int zpos;
};
State – Plane (3/5)
void rcar_du_plane_reset(struct drm_plane *plane)
{
struct rcar_du_plane_state *state;
if (plane->state) {
rcar_du_plane_atomic_destroy_state(
plane, plane->state);
plane->state = NULL;
}
state = kzalloc(sizeof(*state), GFP_KERNEL);
state->hwindex = -1;
state->alpha = 255;
state->colorkey = RCAR_DU_COLORKEY_NONE;
...
plane->state = &state->state;
plane->state->plane = plane;
}
State – Plane (4/5)
struct drm_plane_state *
rcar_du_plane_atomic_duplicate_state(
struct drm_plane *plane)
{
struct rcar_du_plane_state *state;
struct rcar_du_plane_state *copy;
state = to_rcar_plane_state(plane->state);
copy = kmemdup(state, sizeof(*state),
GFP_KERNEL);
__drm_atomic_helper_plane_duplicate_state(
plane, &copy->state);
return &copy->state;
}
State – Plane (5/5)
void rcar_du_plane_atomic_destroy_state(
struct drm_plane *plane,
struct drm_plane_state *state)
{
__drm_atomic_helper_plane_destroy_state(
plane, state);
kfree(to_rcar_plane_state(state));
}
State Manipulation
int drm_atomic_set_crtc_for_plane(
struct drm_plane_state *plane_state,
struct drm_crtc *crtc);
void drm_atomic_set_fb_for_plane(
struct drm_plane_state *plane_state,
struct drm_framebuffer *fb);
int drm_atomic_set_crtc_for_connector(
struct drm_connector_state *conn_state,
struct drm_crtc *crtc);
...
Atomic Update – KMS (1/2)
struct drm_mode_config_funcs mode_config_funcs = {
.atomic_check = ...,
.atomic_commit = ...,
};
int (*atomic_check)(struct drm_device *dev,
struct drm_atomic_state *a);
int (*atomic_commit)(struct drm_device *dev,
struct drm_atomic_state *a,
bool async);
Atomic Update – KMS (2/2)
struct drm_mode_config_funcs mode_config_funcs = {
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
int rcar_du_probe(struct platform_device *pdev)
{
...
drm_crtc_helper_add(crtc, &crtc_helper_funcs);
drm_connector_helper_add(connector,
&connector_helper_funcs);
drm_encoder_helper_add(encoder,
&encoder_helper_funcs);
...
}
CoreHelpers
Atomic Update – CRTC
struct drm_crtc_helper_funcs crtc_helper_funcs = {
.mode_fixup = rcar_du_crtc_mode_fixup,
/* .mode_set_nofb = ..., */
.disable = rcar_du_crtc_disable,
.enable = rcar_du_crtc_enable,
};
bool rcar_du_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{ ... }
void rcar_du_crtc_disable(struct drm_crtc *crtc)
{ ... }
void rcar_du_crtc_enable(struct drm_crtc *crtc)
{ ... }
Atomic Update – Encoder
struct drm_encoder_helper_funcs encoder_helper_funcs = {
.mode_set = rcar_du_encoder_mode_set,
.disable = rcar_du_encoder_disable,
.enable = rcar_du_encoder_enable,
.atomic_check = rcar_du_encoder_atomic_check,
};
struct drm_connector_helper_funcs connector_helper_funcs =
{
.atomic_best_encoder = rcar_du_connector_best_encoder,
/* .best_encoder still used for FBDEV emulation */
};
Atomic Update – CRTC + Plane
struct drm_crtc_helper_funcs crtc_helper_funcs = {
.atomic_begin = rcar_du_crtc_atomic_begin,
.atomic_flush = rcar_du_crtc_atomic_flush,
};
void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
/* Enable vblank processing */
drm_crtc_vblank_get(crtc);
...
}
void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
/* Set the GO bit */
...
}
Atomic Update – Plane (1/2)
struct drm_plane_helper_funcs plane_helper_funcs = {
.prepare_fb = ...,
.cleanup_fb = ...,
};
int (*prepare_fb)(struct drm_plane *plane,
struct drm_framebuffer *fb,
const struct drm_plane_state *new_state);
void (*cleanup_fb)(struct drm_plane *plane,
struct drm_framebuffer *fb,
const struct drm_plane_state *old_state);
Atomic Update – Plane (2/2)
struct drm_plane_helper_funcs plane_helper_funcs = {
.atomic_check = rcar_du_plane_atomic_check,
.atomic_update = rcar_du_plane_atomic_update,
/* .atomic_disable = ..., */
};
int rcar_du_plane_atomic_check(
struct drm_plane *plane,
struct drm_plane_state *state)
{
...
}
void rcar_du_plane_atomic_update(
struct drm_plane *plane,
struct drm_plane_state *old_state)
{
...
}
Vertical Blanking (1/4)
int rcar_du_probe(struct platform_device *pdev)
{
...
drm_vblank_init(dev, 1);
...
}
irqreturn_t rcar_du_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
drm_handle_vblank(dev, 0);
}
Vertical Blanking (2/4)
int rcar_du_enable_vblank(struct drm_device *dev,
int crtc)
{
/* Enable the vblank interrupt for the CRTC */
return 0;
}
void rcar_du_disable_vblank(struct drm_device *dev,
int crtc)
{
/* Disable the vblank interrupt for the CRTC */
}
struct drm_driver rcar_du_driver = {
.get_vblank_counter = drm_vblank_count,
.enable_vblank = rcar_du_enable_vblank,
.disable_vblank = rcar_du_disable_vblank,
};
Vertical Blanking (3/4)
irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
{
struct rcar_du_crtc *rcrtc = arg;
...
drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index);
rcar_du_crtc_finish_page_flip(rcrtc);
return IRQ_HANDLED;
}
Vertical Blanking (4/4)
void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
{
struct drm_pending_vblank_event *event;
struct drm_device *dev = rcrtc->crtc.dev;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
event = rcrtc->event;
rcrtc->event = NULL;
spin_unlock_irqrestore(&dev->event_lock, flags);
if (event == NULL)
return;
spin_lock_irqsave(&dev->event_lock, flags);
drm_send_vblank_event(dev, rcrtc->index, event);
wake_up(&rcrtc->flip_wait);
spin_unlock_irqrestore(&dev->event_lock, flags);
drm_crtc_vblank_put(&rcrtc->crtc);
}
Legacy
struct drm_crtc_funcs crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
};
struct drm_connector_funcs connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms,
};
And Much More...
● properties
● connector status poll
● FBDEV emulation
● ...
Source: http://www.flickr.com/photos/buckaroobay/3721809183/
Ongoing Work
● suspend/resume helpers
● atomic fbdev
● active only plane update
● better runtime PM support
Future Work
● vblank rework
● bridge vs. slave encoder
● write back
● live sources
● fences
● validation
● fastboot
● generic async commit
• Conversion HOWTO for legacy drivers
http://blog.ffwll.ch/2014/11/atomic-modeset-
support-for-kms-drivers.html
• Atomic mode setting design overview (LWN)
https://lwn.net/Articles/653071/
https://lwn.net/Articles/653466/
• DRM DocBook
https://01.org/linuxgraphics/gfx-docs/drm/
Resources
• dri-devel@lists.freedesktop.org
• laurent.pinchart@ideasonboard.com
Contact
? !
thx.

Weitere ähnliche Inhalte

Was ist angesagt?

Ipmi spec ch1~6_simon_20110422
Ipmi spec ch1~6_simon_20110422Ipmi spec ch1~6_simon_20110422
Ipmi spec ch1~6_simon_20110422
davidsmc
 

Was ist angesagt? (20)

Inside Android's UI
Inside Android's UIInside Android's UI
Inside Android's UI
 
GDB Rocks!
GDB Rocks!GDB Rocks!
GDB Rocks!
 
FlashCopy and DB2 for z/OS
FlashCopy and DB2 for z/OSFlashCopy and DB2 for z/OS
FlashCopy and DB2 for z/OS
 
Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)
 
LAS16-403: GDB Linux Kernel Awareness
LAS16-403: GDB Linux Kernel AwarenessLAS16-403: GDB Linux Kernel Awareness
LAS16-403: GDB Linux Kernel Awareness
 
Overlayfs and VFS
Overlayfs and VFSOverlayfs and VFS
Overlayfs and VFS
 
Ipmi spec ch1~6_simon_20110422
Ipmi spec ch1~6_simon_20110422Ipmi spec ch1~6_simon_20110422
Ipmi spec ch1~6_simon_20110422
 
Assembler Language Tutorial for Mainframe Programmers
Assembler Language Tutorial for Mainframe ProgrammersAssembler Language Tutorial for Mainframe Programmers
Assembler Language Tutorial for Mainframe Programmers
 
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
 
Advanced Debugging with GDB
Advanced Debugging with GDBAdvanced Debugging with GDB
Advanced Debugging with GDB
 
Zedroid - Android (5.0 and later) on Zedboard
Zedroid - Android (5.0 and later) on ZedboardZedroid - Android (5.0 and later) on Zedboard
Zedroid - Android (5.0 and later) on Zedboard
 
Introduction to Perf
Introduction to PerfIntroduction to Perf
Introduction to Perf
 
How To Master PACBASE For Mainframe In Only Seven Days
How To Master PACBASE For Mainframe In Only Seven DaysHow To Master PACBASE For Mainframe In Only Seven Days
How To Master PACBASE For Mainframe In Only Seven Days
 
Q4.11: NEON Intrinsics
Q4.11: NEON IntrinsicsQ4.11: NEON Intrinsics
Q4.11: NEON Intrinsics
 
Evolution of Programming Languages
Evolution of Programming LanguagesEvolution of Programming Languages
Evolution of Programming Languages
 
Xvisor: embedded and lightweight hypervisor
Xvisor: embedded and lightweight hypervisorXvisor: embedded and lightweight hypervisor
Xvisor: embedded and lightweight hypervisor
 
Linux Device Tree
Linux Device TreeLinux Device Tree
Linux Device Tree
 
Memory Mapping Implementation (mmap) in Linux Kernel
Memory Mapping Implementation (mmap) in Linux KernelMemory Mapping Implementation (mmap) in Linux Kernel
Memory Mapping Implementation (mmap) in Linux Kernel
 
Linux Internals - Kernel/Core
Linux Internals - Kernel/CoreLinux Internals - Kernel/Core
Linux Internals - Kernel/Core
 
Introduction to Makefile
Introduction to MakefileIntroduction to Makefile
Introduction to Makefile
 

Andere mochten auch

X / DRM (Direct Rendering Manager) Architectural Overview
X / DRM (Direct Rendering Manager) Architectural OverviewX / DRM (Direct Rendering Manager) Architectural Overview
X / DRM (Direct Rendering Manager) Architectural Overview
Moriyoshi Koizumi
 

Andere mochten auch (6)

GS-4112, Mantle: Empowering 3D Graphics Innovation, by Guennadi Riguer and Br...
GS-4112, Mantle: Empowering 3D Graphics Innovation, by Guennadi Riguer and Br...GS-4112, Mantle: Empowering 3D Graphics Innovation, by Guennadi Riguer and Br...
GS-4112, Mantle: Empowering 3D Graphics Innovation, by Guennadi Riguer and Br...
 
Taming the Monster: Digital Preservation Planning and Implementation Tools
Taming the Monster: Digital Preservation Planning and Implementation ToolsTaming the Monster: Digital Preservation Planning and Implementation Tools
Taming the Monster: Digital Preservation Planning and Implementation Tools
 
XPDS13: Zero-copy display of guest framebuffers using GEM - John Baboval, Citrix
XPDS13: Zero-copy display of guest framebuffers using GEM - John Baboval, CitrixXPDS13: Zero-copy display of guest framebuffers using GEM - John Baboval, Citrix
XPDS13: Zero-copy display of guest framebuffers using GEM - John Baboval, Citrix
 
X / DRM (Direct Rendering Manager) Architectural Overview
X / DRM (Direct Rendering Manager) Architectural OverviewX / DRM (Direct Rendering Manager) Architectural Overview
X / DRM (Direct Rendering Manager) Architectural Overview
 
Kernel Recipes 2013 - Overview display in the Linux kernel
Kernel Recipes 2013 - Overview display in the Linux kernelKernel Recipes 2013 - Overview display in the Linux kernel
Kernel Recipes 2013 - Overview display in the Linux kernel
 
De-mystifying DRM
De-mystifying DRMDe-mystifying DRM
De-mystifying DRM
 

Ähnlich wie Kernel Recipes 2015: Anatomy of an atomic KMS driver

Virtual platform
Virtual platformVirtual platform
Virtual platform
sean chen
 
Reversing & malware analysis training part 12 rootkit analysis
Reversing & malware analysis training part 12   rootkit analysisReversing & malware analysis training part 12   rootkit analysis
Reversing & malware analysis training part 12 rootkit analysis
Abdulrahman Bassam
 

Ähnlich wie Kernel Recipes 2015: Anatomy of an atomic KMS driver (20)

426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools
 
Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic Analysis
 
OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference GuideOpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
 
Linux SD/MMC device driver
Linux SD/MMC device driverLinux SD/MMC device driver
Linux SD/MMC device driver
 
Distributed Resource Management Application API (DRMAA) Version 2
Distributed Resource Management Application API (DRMAA) Version 2Distributed Resource Management Application API (DRMAA) Version 2
Distributed Resource Management Application API (DRMAA) Version 2
 
Virtual platform
Virtual platformVirtual platform
Virtual platform
 
OpenCL 2.1 Reference Guide
OpenCL 2.1 Reference GuideOpenCL 2.1 Reference Guide
OpenCL 2.1 Reference Guide
 
[2009 CodeEngn Conference 03] koheung - 윈도우 커널 악성코드에 대한 분석 및 방법
[2009 CodeEngn Conference 03] koheung - 윈도우 커널 악성코드에 대한 분석 및 방법[2009 CodeEngn Conference 03] koheung - 윈도우 커널 악성코드에 대한 분석 및 방법
[2009 CodeEngn Conference 03] koheung - 윈도우 커널 악성코드에 대한 분석 및 방법
 
BOS K8S Meetup - Finetuning LLama 2 Model on GKE.pdf
BOS K8S Meetup - Finetuning LLama 2 Model on GKE.pdfBOS K8S Meetup - Finetuning LLama 2 Model on GKE.pdf
BOS K8S Meetup - Finetuning LLama 2 Model on GKE.pdf
 
leboncoin DataEngineering / Terraform - beginner to advanced
leboncoin DataEngineering / Terraform - beginner to advancedleboncoin DataEngineering / Terraform - beginner to advanced
leboncoin DataEngineering / Terraform - beginner to advanced
 
Study on Android Emulator
Study on Android EmulatorStudy on Android Emulator
Study on Android Emulator
 
FLAR Workflow
FLAR WorkflowFLAR Workflow
FLAR Workflow
 
Kernel Debugging & Profiling
Kernel Debugging & ProfilingKernel Debugging & Profiling
Kernel Debugging & Profiling
 
Kernel Debugging & Profiling
Kernel Debugging & ProfilingKernel Debugging & Profiling
Kernel Debugging & Profiling
 
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
 
Reversing & malware analysis training part 12 rootkit analysis
Reversing & malware analysis training part 12   rootkit analysisReversing & malware analysis training part 12   rootkit analysis
Reversing & malware analysis training part 12 rootkit analysis
 
OpenCL 2.2 Reference Guide
OpenCL 2.2 Reference GuideOpenCL 2.2 Reference Guide
OpenCL 2.2 Reference Guide
 
COSC 426 Lect. 3 -AR Developer Tools
COSC 426 Lect. 3 -AR Developer ToolsCOSC 426 Lect. 3 -AR Developer Tools
COSC 426 Lect. 3 -AR Developer Tools
 
Android 4.2 Internals - Bluetooth and Network
Android 4.2 Internals - Bluetooth and NetworkAndroid 4.2 Internals - Bluetooth and Network
Android 4.2 Internals - Bluetooth and Network
 
Doom Technical Review
Doom Technical ReviewDoom Technical Review
Doom Technical Review
 

Mehr von Anne Nicolas

Kernel Recipes 2019 - GNU poke, an extensible editor for structured binary data
Kernel Recipes 2019 - GNU poke, an extensible editor for structured binary dataKernel Recipes 2019 - GNU poke, an extensible editor for structured binary data
Kernel Recipes 2019 - GNU poke, an extensible editor for structured binary data
Anne Nicolas
 

Mehr von Anne Nicolas (20)

Kernel Recipes 2019 - Driving the industry toward upstream first
Kernel Recipes 2019 - Driving the industry toward upstream firstKernel Recipes 2019 - Driving the industry toward upstream first
Kernel Recipes 2019 - Driving the industry toward upstream first
 
Kernel Recipes 2019 - No NMI? No Problem! – Implementing Arm64 Pseudo-NMI
Kernel Recipes 2019 - No NMI? No Problem! – Implementing Arm64 Pseudo-NMIKernel Recipes 2019 - No NMI? No Problem! – Implementing Arm64 Pseudo-NMI
Kernel Recipes 2019 - No NMI? No Problem! – Implementing Arm64 Pseudo-NMI
 
Kernel Recipes 2019 - Hunting and fixing bugs all over the Linux kernel
Kernel Recipes 2019 - Hunting and fixing bugs all over the Linux kernelKernel Recipes 2019 - Hunting and fixing bugs all over the Linux kernel
Kernel Recipes 2019 - Hunting and fixing bugs all over the Linux kernel
 
Kernel Recipes 2019 - Metrics are money
Kernel Recipes 2019 - Metrics are moneyKernel Recipes 2019 - Metrics are money
Kernel Recipes 2019 - Metrics are money
 
Kernel Recipes 2019 - Kernel documentation: past, present, and future
Kernel Recipes 2019 - Kernel documentation: past, present, and futureKernel Recipes 2019 - Kernel documentation: past, present, and future
Kernel Recipes 2019 - Kernel documentation: past, present, and future
 
Embedded Recipes 2019 - Knowing your ARM from your ARSE: wading through the t...
Embedded Recipes 2019 - Knowing your ARM from your ARSE: wading through the t...Embedded Recipes 2019 - Knowing your ARM from your ARSE: wading through the t...
Embedded Recipes 2019 - Knowing your ARM from your ARSE: wading through the t...
 
Kernel Recipes 2019 - GNU poke, an extensible editor for structured binary data
Kernel Recipes 2019 - GNU poke, an extensible editor for structured binary dataKernel Recipes 2019 - GNU poke, an extensible editor for structured binary data
Kernel Recipes 2019 - GNU poke, an extensible editor for structured binary data
 
Kernel Recipes 2019 - Analyzing changes to the binary interface exposed by th...
Kernel Recipes 2019 - Analyzing changes to the binary interface exposed by th...Kernel Recipes 2019 - Analyzing changes to the binary interface exposed by th...
Kernel Recipes 2019 - Analyzing changes to the binary interface exposed by th...
 
Embedded Recipes 2019 - Remote update adventures with RAUC, Yocto and Barebox
Embedded Recipes 2019 - Remote update adventures with RAUC, Yocto and BareboxEmbedded Recipes 2019 - Remote update adventures with RAUC, Yocto and Barebox
Embedded Recipes 2019 - Remote update adventures with RAUC, Yocto and Barebox
 
Embedded Recipes 2019 - Making embedded graphics less special
Embedded Recipes 2019 - Making embedded graphics less specialEmbedded Recipes 2019 - Making embedded graphics less special
Embedded Recipes 2019 - Making embedded graphics less special
 
Embedded Recipes 2019 - Linux on Open Source Hardware and Libre Silicon
Embedded Recipes 2019 - Linux on Open Source Hardware and Libre SiliconEmbedded Recipes 2019 - Linux on Open Source Hardware and Libre Silicon
Embedded Recipes 2019 - Linux on Open Source Hardware and Libre Silicon
 
Embedded Recipes 2019 - From maintaining I2C to the big (embedded) picture
Embedded Recipes 2019 - From maintaining I2C to the big (embedded) pictureEmbedded Recipes 2019 - From maintaining I2C to the big (embedded) picture
Embedded Recipes 2019 - From maintaining I2C to the big (embedded) picture
 
Embedded Recipes 2019 - Testing firmware the devops way
Embedded Recipes 2019 - Testing firmware the devops wayEmbedded Recipes 2019 - Testing firmware the devops way
Embedded Recipes 2019 - Testing firmware the devops way
 
Embedded Recipes 2019 - Herd your socs become a matchmaker
Embedded Recipes 2019 - Herd your socs become a matchmakerEmbedded Recipes 2019 - Herd your socs become a matchmaker
Embedded Recipes 2019 - Herd your socs become a matchmaker
 
Embedded Recipes 2019 - LLVM / Clang integration
Embedded Recipes 2019 - LLVM / Clang integrationEmbedded Recipes 2019 - LLVM / Clang integration
Embedded Recipes 2019 - LLVM / Clang integration
 
Embedded Recipes 2019 - Introduction to JTAG debugging
Embedded Recipes 2019 - Introduction to JTAG debuggingEmbedded Recipes 2019 - Introduction to JTAG debugging
Embedded Recipes 2019 - Introduction to JTAG debugging
 
Embedded Recipes 2019 - Pipewire a new foundation for embedded multimedia
Embedded Recipes 2019 - Pipewire a new foundation for embedded multimediaEmbedded Recipes 2019 - Pipewire a new foundation for embedded multimedia
Embedded Recipes 2019 - Pipewire a new foundation for embedded multimedia
 
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all started
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all startedKernel Recipes 2019 - ftrace: Where modifying a running kernel all started
Kernel Recipes 2019 - ftrace: Where modifying a running kernel all started
 
Kernel Recipes 2019 - Suricata and XDP
Kernel Recipes 2019 - Suricata and XDPKernel Recipes 2019 - Suricata and XDP
Kernel Recipes 2019 - Suricata and XDP
 
Kernel Recipes 2019 - Marvels of Memory Auto-configuration (SPD)
Kernel Recipes 2019 - Marvels of Memory Auto-configuration (SPD)Kernel Recipes 2019 - Marvels of Memory Auto-configuration (SPD)
Kernel Recipes 2019 - Marvels of Memory Auto-configuration (SPD)
 

Kürzlich hochgeladen

CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Kürzlich hochgeladen (20)

Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

Kernel Recipes 2015: Anatomy of an atomic KMS driver

  • 1. Anatomy of an Atomic KMS Driver Kernel Recipes 2015 Paris Laurent Pinchart laurent.pinchart@ideasonboard.com
  • 3. DRM ● Memory Management ● Vertical Blanking ● Version, Authentication, Master, ...
  • 4. KMS ● Device Model ● Frame Buffer ● Modes ● Page Flip ● Planes ● Cursor, Gamma, ...
  • 5. Device Model Frame Buffer (memory) CRTC Encoder Connector Planes (memory) Encoder Connector Connector
  • 6. Device Model - SoC Frame Buffer (memory) CRTC Encoder Connector Plane (memory) SoCMemory Off-Chip Encoder Connector
  • 9. KMS – Frame Buffer CRTC Frame Buffer GEM Object(s) Memory ● width ● height ● format ● pitches ● offsets Properties
  • 10. DRM/KMS – GEM Object CRTC Frame Buffer GEM Object ● width ● height ● bpp ● pitch ● size Properties Memory
  • 11. DRM – Handles Process A Local Handle GEM Object Process B Send FD SCM_RIGHTS Global FD 1 2 Global FD 4 Local Handle 3
  • 12. Active Area KMS – Modes (1/2) sync back porch front porch active area
  • 13. Active Area KMS – Modes (2/2) sync back porch front porch active area hdisplay hsync_start htotal hsync_end
  • 14. KMS – Mode Setting crtc fb Active Area x y mode.hdisplay mode.vdisplay *connectors num_connectors mode struct drm_mode_set { struct drm_framebuffer *fb; struct drm_crtc *crtc; struct drm_display_mode *mode; uint32_t x; uint32_t y; struct drm_connector **connectors; size_t num_connectors; };
  • 15. KMS – Page Flipping crtc fb *connectors num_connectors struct drm_mode_crtc_page_flip { __u32 crtc_id; __u32 fb_id; __u32 flags; __u32 reserved; __u64 user_data; }; plane
  • 16. KMS – Atomic Update fb Active Area offset pitch width height mode connectors crtc connector plane state DRM_IOCTL_ MODE_ATOMIC Properties
  • 17. KMS – Atomic Update crtc connector plane device ->atomic_commit() crtc connector plane state Properties ->atomic_check()
  • 18. KMS – Atomic Update #define DRM_MODE_PAGE_FLIP_EVENT 0x01 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02 #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 #define DRM_MODE_ATOMIC_NONBLOCK 0x0200 #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400 struct drm_mode_atomic { __u32 flags; __u32 count_objs; __u64 objs_ptr; __u64 count_props_ptr; __u64 props_ptr; __u64 prop_values_ptr; __u64 reserved; __u64 user_data; };
  • 20. Disclaimer Code Ahead Locking and error handling omitted for readability
  • 21. drm_* = core (rcar_du_)* = driver Cheat Sheet
  • 22. Device Probe (1/2) struct drm_driver rcar_du_driver = { ... }; int rcar_du_probe(struct platform_device *pdev) { struct drm_device *dev; ... dev = drm_dev_alloc(&rcar_du_driver, &pdev->dev); ... }
  • 23. Device Probe (2/2) int rcar_du_probe(struct platform_device *pdev) { struct rcar_du_device *rcdu; struct drm_device *dev; ... rcdu = kzalloc(sizeof(*rcdu), GFP_KERNEL); dev->dev_private = rcdu; /* Memory, clocks, regulators, ... */ ... drm_dev_register(dev, 0); ... }
  • 24. Device Removal int rcar_du_remove(struct platform_device *pdev) { struct rcar_du_device *rcdu = platform_get_drvdata(pdev); struct drm_device *dev = rcdu->ddev; drm_dev_unregister(dev); ... drm_dev_unref(dev); return 0; }
  • 25. Driver Information struct drm_driver rcar_du_driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .name = "rcar-du", .desc = "Renesas R-Car Display Unit", .date = "20130110", .major = 1, .minor = 0, .patchlevel = 0, ... };
  • 26. File Operations struct file_operations rcar_du_fops = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, .unlocked_ioctl = drm_ioctl, .compat_ioctl = drm_compat_ioctl, .poll = drm_poll, .read = drm_read, .fasync = drm_fasync, .llseek = no_llseek, .mmap = ..., }; struct drm_driver rcar_du_driver = { .fops = &rcar_du_fops, };
  • 27. IRQ Installation int rcar_du_probe(struct platform_device *pdev) { ... drm_irq_install(dev); /* Behind the scene: * request_irq(platform_get_irq(..., 0)) */ ... } struct drm_driver rcar_du_driver = { /* .irq_preinstall */ .irq_handler = rcar_du_irq, /* .irq_postinstall */ };
  • 28. Mode Config struct drm_mode_config_funcs modecfg_funcs = { .fb_create = ..., }; int rcar_du_probe(struct platform_device *pdev) { ... drm_mode_config_init(dev); dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; dev->mode_config.max_width = 4095; dev->mode_config.max_height = 2047; dev->mode_config.funcs = &rcar_du_modecfg_funcs; ... }
  • 29. GEM struct file_operations rcar_du_fops = { .mmap = drm_gem_cma_mmap, }; struct drm_driver rcar_du_driver = { .gem_free_object = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, };
  • 30. GEM – Dumb Objects struct drm_driver rcar_du_driver = { .dumb_create = drm_gem_cma_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, .dumb_destroy = drm_gem_cma_dumb_destroy, };
  • 31. GEM – PRIME struct drm_driver rcar_du_driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import = drm_gem_cma_dmabuf_import, .gem_prime_export = drm_gem_cma_dmabuf_export, };
  • 32. Frame Buffer drm_framebuffer * rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) { /* Validate the pixel format, size and pitches */ ... return drm_fb_cma_create(dev, file_priv, mode_cmd); } struct drm_mode_config_funcs rcar_du_modecfg_funcs = { .fb_create = rcar_du_fb_create, };
  • 33. Initialization – CRTC struct drm_crtc_funcs crtc_funcs = { .destroy = drm_crtc_cleanup, ... }; int rcar_du_probe(struct platform_device *pdev) { struct drm_device *dev; struct drm_crtc *crtc; ... drm_crtc_init(dev, crtc, &crtc_funcs); ... }
  • 34. Initialization – Encoder struct drm_encoder_funcs encoder_funcs = { .destroy = drm_encoder_cleanup, }; int rcar_du_probe(struct platform_device *pdev) { struct drm_device *dev; struct drm_encoder *encoder; ... encoder->possible_crtcs = 1 << crtc; drm_encoder_init(dev, encoder, &encoder_funcs, DRM_MODE_ENCODER_DAC); ... }
  • 35. Initialization – Connector struct drm_connector_funcs connector_funcs = { .destroy = drm_connector_cleanup, ... }; int rcar_du_probe(struct platform_device *pdev) { struct drm_device *dev; struct drm_connector *connector; ... connector->display_info.width_mm = ...; connector->display_info.height_mm = ...; drm_connector_init(dev, connector, &connector_funcs, DRM_MODE_CONNECTOR_VGA); drm_connector_register(connector); drm_mode_connector_attach_encoder(connector, encoder); }
  • 36. Initialization – Plane struct drm_plane_funcs plane_funcs = { .destroy = drm_plane_cleanup, ... }; uint32_t formats[] = { DRM_FORMAT_RGB565, ... }; int rcar_du_probe(struct platform_device *pdev) { struct drm_plane *plane = ...; ... drm_universal_plane_init(dev, plane, crtcs, &plane_funcs, formats, ARRAY_SIZE(formats), DRM_PLANE_TYPE_PRIMARY); /* DRM_PLANE_TYPE_OVERLAY */ }
  • 37. Modes Discovery (1/2) struct drm_connector_funcs connector_funcs = { .fill_modes = ..., }; int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
  • 38. Modes Discovery (2/2) struct drm_connector_funcs connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, }; struct drm_connector_helper_funcs connector_helper_funcs = { .get_modes = rcar_du_vga_connector_get_modes, .mode_valid = rcar_du_vga_connector_mode_valid, }; CoreHelpers
  • 39. State – CRTC struct drm_crtc_funcs crtc_funcs = { .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; struct drm_crtc_state { struct drm_crtc *crtc; bool enable; bool active; bool planes_changed : 1; bool mode_changed : 1; bool active_changed : 1; ... };
  • 40. State – Connector struct drm_connector_funcs connector_funcs = { .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; struct drm_connector_state { struct drm_connector *connector; struct drm_crtc *crtc; struct drm_encoder *best_encoder; struct drm_atomic_state *state; };
  • 41. State – Plane (1/5) struct drm_plane_funcs plane_funcs = { .reset = rcar_du_plane_reset, .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state, .atomic_destroy_state = rcar_du_plane_atomic_destroy_state, }; struct drm_plane_state { struct drm_plane *plane; struct drm_crtc *crtc; struct drm_framebuffer *fb; struct fence *fence; int32_t crtc_x, crtc_y; uint32_t crtc_w, crtc_h; ... };
  • 42. State – Plane (2/5) struct rcar_du_plane_state { struct drm_plane_state state; const struct rcar_du_format_info *format; int hwindex; unsigned int alpha; unsigned int colorkey; unsigned int zpos; };
  • 43. State – Plane (3/5) void rcar_du_plane_reset(struct drm_plane *plane) { struct rcar_du_plane_state *state; if (plane->state) { rcar_du_plane_atomic_destroy_state( plane, plane->state); plane->state = NULL; } state = kzalloc(sizeof(*state), GFP_KERNEL); state->hwindex = -1; state->alpha = 255; state->colorkey = RCAR_DU_COLORKEY_NONE; ... plane->state = &state->state; plane->state->plane = plane; }
  • 44. State – Plane (4/5) struct drm_plane_state * rcar_du_plane_atomic_duplicate_state( struct drm_plane *plane) { struct rcar_du_plane_state *state; struct rcar_du_plane_state *copy; state = to_rcar_plane_state(plane->state); copy = kmemdup(state, sizeof(*state), GFP_KERNEL); __drm_atomic_helper_plane_duplicate_state( plane, &copy->state); return &copy->state; }
  • 45. State – Plane (5/5) void rcar_du_plane_atomic_destroy_state( struct drm_plane *plane, struct drm_plane_state *state) { __drm_atomic_helper_plane_destroy_state( plane, state); kfree(to_rcar_plane_state(state)); }
  • 46. State Manipulation int drm_atomic_set_crtc_for_plane( struct drm_plane_state *plane_state, struct drm_crtc *crtc); void drm_atomic_set_fb_for_plane( struct drm_plane_state *plane_state, struct drm_framebuffer *fb); int drm_atomic_set_crtc_for_connector( struct drm_connector_state *conn_state, struct drm_crtc *crtc); ...
  • 47. Atomic Update – KMS (1/2) struct drm_mode_config_funcs mode_config_funcs = { .atomic_check = ..., .atomic_commit = ..., }; int (*atomic_check)(struct drm_device *dev, struct drm_atomic_state *a); int (*atomic_commit)(struct drm_device *dev, struct drm_atomic_state *a, bool async);
  • 48. Atomic Update – KMS (2/2) struct drm_mode_config_funcs mode_config_funcs = { .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; int rcar_du_probe(struct platform_device *pdev) { ... drm_crtc_helper_add(crtc, &crtc_helper_funcs); drm_connector_helper_add(connector, &connector_helper_funcs); drm_encoder_helper_add(encoder, &encoder_helper_funcs); ... } CoreHelpers
  • 49. Atomic Update – CRTC struct drm_crtc_helper_funcs crtc_helper_funcs = { .mode_fixup = rcar_du_crtc_mode_fixup, /* .mode_set_nofb = ..., */ .disable = rcar_du_crtc_disable, .enable = rcar_du_crtc_enable, }; bool rcar_du_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { ... } void rcar_du_crtc_disable(struct drm_crtc *crtc) { ... } void rcar_du_crtc_enable(struct drm_crtc *crtc) { ... }
  • 50. Atomic Update – Encoder struct drm_encoder_helper_funcs encoder_helper_funcs = { .mode_set = rcar_du_encoder_mode_set, .disable = rcar_du_encoder_disable, .enable = rcar_du_encoder_enable, .atomic_check = rcar_du_encoder_atomic_check, }; struct drm_connector_helper_funcs connector_helper_funcs = { .atomic_best_encoder = rcar_du_connector_best_encoder, /* .best_encoder still used for FBDEV emulation */ };
  • 51. Atomic Update – CRTC + Plane struct drm_crtc_helper_funcs crtc_helper_funcs = { .atomic_begin = rcar_du_crtc_atomic_begin, .atomic_flush = rcar_du_crtc_atomic_flush, }; void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { /* Enable vblank processing */ drm_crtc_vblank_get(crtc); ... } void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { /* Set the GO bit */ ... }
  • 52. Atomic Update – Plane (1/2) struct drm_plane_helper_funcs plane_helper_funcs = { .prepare_fb = ..., .cleanup_fb = ..., }; int (*prepare_fb)(struct drm_plane *plane, struct drm_framebuffer *fb, const struct drm_plane_state *new_state); void (*cleanup_fb)(struct drm_plane *plane, struct drm_framebuffer *fb, const struct drm_plane_state *old_state);
  • 53. Atomic Update – Plane (2/2) struct drm_plane_helper_funcs plane_helper_funcs = { .atomic_check = rcar_du_plane_atomic_check, .atomic_update = rcar_du_plane_atomic_update, /* .atomic_disable = ..., */ }; int rcar_du_plane_atomic_check( struct drm_plane *plane, struct drm_plane_state *state) { ... } void rcar_du_plane_atomic_update( struct drm_plane *plane, struct drm_plane_state *old_state) { ... }
  • 54. Vertical Blanking (1/4) int rcar_du_probe(struct platform_device *pdev) { ... drm_vblank_init(dev, 1); ... } irqreturn_t rcar_du_irq(int irq, void *arg) { struct drm_device *dev = arg; drm_handle_vblank(dev, 0); }
  • 55. Vertical Blanking (2/4) int rcar_du_enable_vblank(struct drm_device *dev, int crtc) { /* Enable the vblank interrupt for the CRTC */ return 0; } void rcar_du_disable_vblank(struct drm_device *dev, int crtc) { /* Disable the vblank interrupt for the CRTC */ } struct drm_driver rcar_du_driver = { .get_vblank_counter = drm_vblank_count, .enable_vblank = rcar_du_enable_vblank, .disable_vblank = rcar_du_disable_vblank, };
  • 56. Vertical Blanking (3/4) irqreturn_t rcar_du_crtc_irq(int irq, void *arg) { struct rcar_du_crtc *rcrtc = arg; ... drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index); rcar_du_crtc_finish_page_flip(rcrtc); return IRQ_HANDLED; }
  • 57. Vertical Blanking (4/4) void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc) { struct drm_pending_vblank_event *event; struct drm_device *dev = rcrtc->crtc.dev; unsigned long flags; spin_lock_irqsave(&dev->event_lock, flags); event = rcrtc->event; rcrtc->event = NULL; spin_unlock_irqrestore(&dev->event_lock, flags); if (event == NULL) return; spin_lock_irqsave(&dev->event_lock, flags); drm_send_vblank_event(dev, rcrtc->index, event); wake_up(&rcrtc->flip_wait); spin_unlock_irqrestore(&dev->event_lock, flags); drm_crtc_vblank_put(&rcrtc->crtc); }
  • 58. Legacy struct drm_crtc_funcs crtc_funcs = { .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, }; struct drm_connector_funcs connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, };
  • 59. And Much More... ● properties ● connector status poll ● FBDEV emulation ● ...
  • 61. Ongoing Work ● suspend/resume helpers ● atomic fbdev ● active only plane update ● better runtime PM support
  • 62. Future Work ● vblank rework ● bridge vs. slave encoder ● write back ● live sources ● fences ● validation ● fastboot ● generic async commit
  • 63. • Conversion HOWTO for legacy drivers http://blog.ffwll.ch/2014/11/atomic-modeset- support-for-kms-drivers.html • Atomic mode setting design overview (LWN) https://lwn.net/Articles/653071/ https://lwn.net/Articles/653466/ • DRM DocBook https://01.org/linuxgraphics/gfx-docs/drm/ Resources
  • 65. ? !
  • 66. thx.